From 00ce7d93ce384972e1746dd68a6ed0f1367b0969 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 03:56:02 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Sqlite=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sqlite/SqliteExpression/DateTimeTest.cs | 66 +++++++++++++------ .../SqliteExpression.cs | 52 ++++++++++++++- 2 files changed, 97 insertions(+), 21 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index 7afc0189..0ca17964 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.SqliteExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.sqlite.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("ÉÏÎç", "AM").Replace("ÏÂÎç", "PM").Replace("ÉÏ", "A").Replace("ÏÂ", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.SqliteExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 325aa535..5c1ab0fa 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Sqlite { @@ -396,7 +397,56 @@ namespace FreeSql.Sqlite break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "ToString": return exp.Arguments.Count == 0 ? $"strftime('%Y-%m-%d %H:%M.%f',{left})" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"strftime('%Y-%m-%d %H:%M:%f',{left})"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"strftime('%Y-%m-%d %H:%M:%S',{left})"; + case "'yyyy-MM-dd HH:mm'": return $"strftime('%Y-%m-%d %H:%M',{left})"; + case "'yyyy-MM-dd HH'": return $"strftime('%Y-%m-%d %H',{left})"; + case "'yyyy-MM-dd'": return $"strftime('%Y-%m-%d',{left})"; + case "'yyyy-MM'": return $"strftime('%Y-%m',{left})"; + case "'yyyyMMddHHmmss'": return $"strftime('%Y%m%d%H%M%S',{left})"; + case "'yyyyMMddHHmm'": return $"strftime('%Y%m%d%H%M',{left})"; + case "'yyyyMMddHH'": return $"strftime('%Y%m%d%H',{left})"; + case "'yyyyMMdd'": return $"strftime('%Y%m%d',{left})"; + case "'yyyyMM'": return $"strftime('%Y%m',{left})"; + case "'yyyy'": return $"strftime('%Y',{left})"; + case "'HH:mm:ss'": return $"strftime('%H:%M:%S',{left})"; + } + args1 = Regex.Replace(args1, "(yyyy|MM|dd|HH|mm|ss)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"%Y"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "mm": return $"%_a4"; + case "ss": return $"%S"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(yy|M|d|H|hh|h|m|s|tt|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "yy": return $"',{left}) || substr(strftime('%Y',{left}),3,2) || strftime('"; + case "M": return $"',{left}) || ltrim(strftime('%m',{left}),'0') || strftime('"; + case "d": return $"',{left}) || ltrim(strftime('%d',{left}),'0') || strftime('"; + case "H": return $"',{left}) || case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end || strftime('"; + case "hh": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end || strftime('"; + case "h": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end || strftime('"; + case "m": return $"',{left}) || case when substr(strftime('%M',{left}),1,1) = '0' then substr(strftime('%M',{left}),2,1) else strftime('%M',{left}) end || strftime('"; + case "s": return $"',{left}) || case when substr(strftime('%S',{left}),1,1) = '0' then substr(strftime('%S',{left}),2,1) else strftime('%S',{left}) end || strftime('"; + case "tt": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'PM' else 'AM' end || strftime('"; + case "t": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'P' else 'A' end || strftime('"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "%m").Replace("%_a2", "%d").Replace("%_a3", "%H").Replace("%_a4", "%M"); + return isMatched == false ? $"strftime({args1},{left})" : $"(strftime({args1},{left}))".Replace($"strftime('',{left})", "''"); } } return null;