@@ -11,14 +11,20 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal;
11
11
/// any release. You should only use it directly in your code with extreme caution and knowing that
12
12
/// doing so can result in application failures when updating to a new Entity Framework Core release.
13
13
/// </summary>
14
- public class SqliteDateTimeAddTranslator : IMethodCallTranslator
14
+ public class SqliteDateTimeMethodTranslator : IMethodCallTranslator
15
15
{
16
16
private static readonly MethodInfo AddMilliseconds
17
17
= typeof ( DateTime ) . GetRuntimeMethod ( nameof ( DateTime . AddMilliseconds ) , new [ ] { typeof ( double ) } ) ! ;
18
18
19
19
private static readonly MethodInfo AddTicks
20
20
= typeof ( DateTime ) . GetRuntimeMethod ( nameof ( DateTime . AddTicks ) , new [ ] { typeof ( long ) } ) ! ;
21
21
22
+ private static readonly MethodInfo ToUnixTimeSeconds
23
+ = typeof ( DateTimeOffset ) . GetRuntimeMethod ( nameof ( DateTimeOffset . ToUnixTimeSeconds ) , Type . EmptyTypes ) ! ;
24
+
25
+ private static readonly MethodInfo ToUnixTimeMilliseconds
26
+ = typeof ( DateTimeOffset ) . GetRuntimeMethod ( nameof ( DateTimeOffset . ToUnixTimeMilliseconds ) , Type . EmptyTypes ) ! ;
27
+
22
28
private readonly Dictionary < MethodInfo , string > _methodInfoToUnitSuffix = new ( )
23
29
{
24
30
{ typeof ( DateTime ) . GetRuntimeMethod ( nameof ( DateTime . AddYears ) , new [ ] { typeof ( int ) } ) ! , " years" } ,
@@ -40,7 +46,7 @@ private static readonly MethodInfo AddTicks
40
46
/// any release. You should only use it directly in your code with extreme caution and knowing that
41
47
/// doing so can result in application failures when updating to a new Entity Framework Core release.
42
48
/// </summary>
43
- public SqliteDateTimeAddTranslator ( SqliteSqlExpressionFactory sqlExpressionFactory )
49
+ public SqliteDateTimeMethodTranslator ( SqliteSqlExpressionFactory sqlExpressionFactory )
44
50
{
45
51
_sqlExpressionFactory = sqlExpressionFactory ;
46
52
}
@@ -60,7 +66,9 @@ public SqliteDateTimeAddTranslator(SqliteSqlExpressionFactory sqlExpressionFacto
60
66
? TranslateDateTime ( instance , method , arguments )
61
67
: method . DeclaringType == typeof ( DateOnly )
62
68
? TranslateDateOnly ( instance , method , arguments )
63
- : null ;
69
+ : method . DeclaringType == typeof ( DateTimeOffset )
70
+ ? TranslateDateTimeOffset ( instance , method , arguments )
71
+ : null ;
64
72
65
73
private SqlExpression ? TranslateDateTime (
66
74
SqlExpression ? instance ,
@@ -145,4 +153,40 @@ public SqliteDateTimeAddTranslator(SqliteSqlExpressionFactory sqlExpressionFacto
145
153
146
154
return null ;
147
155
}
156
+
157
+ private SqlExpression ? TranslateDateTimeOffset (
158
+ SqlExpression ? instance ,
159
+ MethodInfo method ,
160
+ IReadOnlyList < SqlExpression > arguments )
161
+ {
162
+ if ( ToUnixTimeSeconds . Equals ( method ) )
163
+ {
164
+ return _sqlExpressionFactory . Function (
165
+ "unixepoch" ,
166
+ new [ ]
167
+ {
168
+ instance !
169
+ } ,
170
+ argumentsPropagateNullability : new [ ] { true , true } ,
171
+ nullable : true ,
172
+ returnType : method . ReturnType ) ;
173
+ }
174
+ else if ( ToUnixTimeMilliseconds . Equals ( method ) )
175
+ {
176
+ return _sqlExpressionFactory . Convert (
177
+ _sqlExpressionFactory . Multiply (
178
+ _sqlExpressionFactory . Subtract (
179
+ _sqlExpressionFactory . Function (
180
+ "julianday" ,
181
+ new [ ] { instance ! } ,
182
+ nullable : true ,
183
+ argumentsPropagateNullability : new [ ] { true } ,
184
+ typeof ( double ) ) ,
185
+ _sqlExpressionFactory . Constant ( 2440587.5 ) ) , // NB: Result of julianday('1970-01-01 00:00:00')
186
+ _sqlExpressionFactory . Constant ( TimeSpan . TicksPerDay ) ) ,
187
+ typeof ( long ) ) ;
188
+ }
189
+
190
+ return null ;
191
+ }
148
192
}
0 commit comments