@@ -361,35 +361,106 @@ public static bool EqualIsNull<TValue>(TValue value1)
361361 expContext . Value . Result = $ "{ expContext . Value . ParsedContent [ "value1" ] } IS NULL";
362362 return false ;
363363 }
364- #endregion
364+ #endregion
365365
366- #region 时间比较
367- /// <summary>
368- /// 计算两个日期之间的差异
369- /// 时间2 - 时间1
370- /// </summary>
371- /// <param name="datePart"></param>
372- /// <param name="dateTimeOffset1"></param>
373- /// <param name="dateTimeOffset2"></param>
374- public static long DateDiff ( string datePart , DateTimeOffset dateTimeOffset1 , DateTimeOffset dateTimeOffset2 )
375- {
376- var up = expContext . Value ;
366+ #region 时间比较
367+ private static void InternalDateDiff ( string datePart , string arg1Name , string arg2Name )
368+ {
369+ var up = expContext . Value ;
370+ var dt1 = up . ParsedContent [ arg1Name ] ;
371+ var dt2 = up . ParsedContent [ arg2Name ] ;
377372
378- // 根据不同数据库类型定义不同的 SQL 语句
379- if ( up . DataType == DataType . SqlServer )
380- {
381- up . Result = $ "DATEDIFF({ datePart } , { up . ParsedContent [ "dateTimeOffset1" ] } , { up . ParsedContent [ "dateTimeOffset2" ] } )";
382- }
383- else if ( up . DataType == DataType . MySql )
384- {
385- up . Result = $ "TIMESTAMPDIFF({ datePart } , { up . ParsedContent [ "dateTimeOffset1" ] } , { up . ParsedContent [ "dateTimeOffset2" ] } )";
386- }
387- else
388- {
389- throw new NotImplementedException ( "不支持的数据库类型" ) ;
390- }
391- return 0 ;
392- }
373+ // 统一处理 datePart:部分数据库需要带单引号,部分不需要
374+ // 这里假设传入的 datePart 已经是符合 SQL Server 风格的关键字(如 year, month, day, hour 等)
375+ string part = datePart . Trim ( '\' ' , '"' ) ;
376+
377+ switch ( up . DataType )
378+ {
379+ case DataType . SqlServer :
380+ case DataType . Dameng :
381+ case DataType . Xugu :
382+ up . Result = $ "DATEDIFF({ part } , { dt1 } , { dt2 } )";
383+ break ;
384+
385+ case DataType . MySql :
386+ case DataType . OdbcMySql :
387+ case DataType . CustomMySql :
388+ case DataType . GBase :
389+ up . Result = $ "TIMESTAMPDIFF({ part . ToUpper ( ) } , { dt1 } , { dt2 } )";
390+ break ;
391+
392+ case DataType . PostgreSQL :
393+ case DataType . OdbcPostgreSQL :
394+ case DataType . CustomPostgreSQL :
395+ case DataType . KingbaseES :
396+ case DataType . ShenTong :
397+ if ( part . ToLower ( ) == "day" || part . ToLower ( ) == "d" )
398+ up . Result = $ "(DATE_PART('day', { dt2 } - { dt1 } ))";
399+ else if ( part . ToLower ( ) == "second" || part . ToLower ( ) == "s" )
400+ up . Result = $ "(EXTRACT(EPOCH FROM ({ dt2 } - { dt1 } )))";
401+ else if ( part . ToLower ( ) == "minute" )
402+ up . Result = $ "(EXTRACT(EPOCH FROM ({ dt2 } - { dt1 } )) / 60)";
403+ else if ( part . ToLower ( ) == "hour" )
404+ up . Result = $ "(EXTRACT(EPOCH FROM ({ dt2 } - { dt1 } )) / 3600)";
405+ else if ( part . ToLower ( ) == "month" )
406+ up . Result = $ "(EXTRACT(YEAR FROM AGE({ dt2 } , { dt1 } )) * 12 + EXTRACT(MONTH FROM AGE({ dt2 } , { dt1 } )))";
407+ else if ( part . ToLower ( ) == "year" )
408+ up . Result = $ "(EXTRACT(YEAR FROM AGE({ dt2 } , { dt1 } )))";
409+ else
410+ throw new NotImplementedException ( $ "PostgreSQL 不支持 datePart: { part } ") ;
411+ break ;
412+
413+ case DataType . Oracle :
414+ case DataType . OdbcOracle :
415+ case DataType . CustomOracle :
416+ if ( part . ToLower ( ) == "day" || part . ToLower ( ) == "d" )
417+ up . Result = $ "TRUNC(CAST({ dt2 } AS DATE) - CAST({ dt1 } AS DATE))";
418+ else if ( part . ToLower ( ) == "month" )
419+ up . Result = $ "MONTHS_BETWEEN({ dt2 } , { dt1 } )";
420+ else if ( part . ToLower ( ) == "year" )
421+ up . Result = $ "MONTHS_BETWEEN({ dt2 } , { dt1 } ) / 12";
422+ else
423+ up . Result = $ "(CAST({ dt2 } AS DATE) - CAST({ dt1 } AS DATE)) * { ( part . ToLower ( ) == "hour" ? 24 : part . ToLower ( ) == "minute" ? 1440 : 86400 ) } ";
424+ break ;
425+
426+ case DataType . Sqlite :
427+ if ( part . ToLower ( ) == "day" || part . ToLower ( ) == "d" )
428+ up . Result = $ "(julianday({ dt2 } ) - julianday({ dt1 } ))";
429+ else if ( part . ToLower ( ) == "second" )
430+ up . Result = $ "(julianday({ dt2 } ) - julianday({ dt1 } )) * 86400.0";
431+ else
432+ up . Result = $ "CAST((strftime('%s', { dt2 } ) - strftime('%s', { dt1 } )) AS INTEGER)";
433+ break ;
434+
435+ case DataType . ClickHouse :
436+ up . Result = $ "dateDiff('{ part . ToLower ( ) } ', { dt1 } , { dt2 } )";
437+ break ;
438+ case DataType . DuckDB :
439+ up . Result = $ "date_diff('{ part . ToLower ( ) } ', { dt1 } , { dt2 } )";
440+ break ;
441+ case DataType . Firebird :
442+ up . Result = $ "datediff({ part } from { dt1 } to { dt2 } )";
443+ break ;
444+ case DataType . TDengine :
445+ up . Result = $ "timediff({ dt2 } , { dt1 } )";
446+ break ;
447+
448+ default :
449+ throw new NotImplementedException ( $ "暂不支持数据库类型: { up . DataType } 的 DateDiff 操作") ;
450+ }
451+ }
452+ /// <summary>
453+ /// 计算两个日期之间的差异
454+ /// 时间2 - 时间1
455+ /// </summary>
456+ /// <param name="datePart"></param>
457+ /// <param name="dateTimeOffset1"></param>
458+ /// <param name="dateTimeOffset2"></param>
459+ public static long DateDiff ( string datePart , DateTimeOffset dateTimeOffset1 , DateTimeOffset dateTimeOffset2 )
460+ {
461+ InternalDateDiff ( datePart , nameof ( dateTimeOffset1 ) , nameof ( dateTimeOffset2 ) ) ;
462+ return 0 ;
463+ }
393464 /// <summary>
394465 /// 计算两个日期之间的差异
395466 /// 时间2 - 时间1
@@ -399,23 +470,9 @@ public static long DateDiff(string datePart, DateTimeOffset dateTimeOffset1, Dat
399470 /// <param name="dateTime2">时间2</param>
400471 public static long DateDiff ( string datePart , DateTime dateTime1 , DateTime dateTime2 )
401472 {
402- var up = expContext . Value ;
403-
404- // 根据不同数据库类型定义不同的 SQL 语句
405- if ( up . DataType == DataType . SqlServer )
406- {
407- up . Result = $ "DATEDIFF({ datePart } , { up . ParsedContent [ "dateTimeOffset1" ] } , { up . ParsedContent [ "dateTimeOffset2" ] } )";
408- }
409- else if ( up . DataType == DataType . MySql )
410- {
411- up . Result = $ "TIMESTAMPDIFF({ datePart } , { up . ParsedContent [ "dateTimeOffset1" ] } , { up . ParsedContent [ "dateTimeOffset2" ] } )";
412- }
413- else
414- {
415- throw new NotImplementedException ( "不支持的数据库类型" ) ;
416- }
417- return 0 ;
418- }
473+ InternalDateDiff ( datePart , nameof ( dateTime1 ) , nameof ( dateTime2 ) ) ;
474+ return 0 ;
475+ }
419476 #endregion
420477
421478 /// <summary>
0 commit comments