首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 日期時間間隔計算:Between 與 Span 系列函數完整對比

     編輯:Delphi

DateUtils 時間間隔雙模式深度解析

DateUtils 提供了兩套時間間隔計算函數:Between 系列返回整數(向下取整),Span 系列返回 Double(精確小數)。理解它們的差異與適用場景,能避免業務邏輯中的精度陷阱。

函數對照表

時間單位Between 系列 (Integer)Span 系列 (Double)
年YearsBetweenYearSpan
月MonthsBetweenMonthSpan
週WeeksBetweenWeekSpan
日DaysBetweenDaySpan
時HoursBetweenHourSpan
分MinutesBetweenMinuteSpan
秒SecondsBetweenSecondSpan
毫秒MilliSecondsBetweenMilliSecondSpan

核心差異示範

uses DateUtils;

procedure TForm1.FormCreate(Sender: TObject);
var
  t1, t2: TDateTime;
  i: Int64;
  d: Double;
begin
  t1 := StrToDateTime('2024-05-20 11:22:33');
  t2 := StrToDateTime('2025-09-21 22:33:44');

  // Between 系列:整數,向下取整
  i := YearsBetween(t1, t2);        // 1
  i := MonthsBetween(t1, t2);       // 16
  i := WeeksBetween(t1, t2);        // 70
  i := DaysBetween(t1, t2);         // 489
  i := HoursBetween(t1, t2);        // 11747
  i := MinutesBetween(t1, t2);      // 704845
  i := SecondsBetween(t1, t2);      // 42290711
  i := MilliSecondsBetween(t1, t2); // 42290711000

  // 參數順序不影響結果(取絕對值)
  i := YearsBetween(t2, t1);        // 1

  // Span 系列:Double,精確小數
  d := YearSpan(t1, t2);            // 1.34...
  d := MonthSpan(t1, t2);           // 16.09...
  d := WeekSpan(t1, t2);            // 69.85...
  d := DaySpan(t1, t2);             // 489.46...
  d := HourSpan(t1, t2);            // 11747.18...
  d := MinuteSpan(t1, t2);          // 704831.18...
  d := SecondSpan(t1, t2);          // 42290711.0
  d := MilliSecondSpan(t1, t2);     // 42290711000.0
end;

選擇指南

使用 Between 系列的場景

  • 年齡計算:YearsBetween(BirthDate, Today)
  • 訂閱到期判斷:MonthsBetween(StartDate, Now) >= 12
  • 整週/整日統計:報表分組、考勤天數
  • 倒計時顯示:需整數單位的 UI

使用 Span 系列的場景

  • 精確計費:按小時/分鐘計費的雲服務、停車場
  • 科學計算:物理模擬、天文軌道需高精度
  • 進度百分比:DaySpan(Start, Now) / DaySpan(Start, End) * 100
  • 平均值計算:平均每天/每小時產出量

進階技巧

自定義間隔單位

// 精確到半天的間隔
function HalfDaysBetween(const ANow, AThen: TDateTime): Integer;
begin
  Result := HoursBetween(ANow, AThen) div 12;
end;

// 精確到 15 分鐘
function QuarterHoursBetween(const ANow, AThen: TDateTime): Integer;
begin
  Result := MinutesBetween(ANow, AThen) div 15;
end;

處理負數間隔

// Between 系列已內建取絕對值,Span 系列需手動處理
function SignedDaySpan(const AStart, AEnd: TDateTime): Double;
begin
  Result := DaySpan(AStart, AEnd);
  if AStart > AEnd then Result := -Result;
end;

效能與精度提示

  • 兩系列內部均基于 TDateTime 的 Double 減法運算,效能極高
  • MilliSecondsBetween 返回 Int64,跨度約 292471 年才溢位,足夠安全
  • 月/年間隔涉及曆法邊界(閏年、大小月),Between 系列採用「完整月/年」計數邏輯

掌握 Between 與 Span 的精度語義差異,是編寫正確時間業務邏輯的關鍵。記住口訣:「整數用 Between,小數用 Span,月年看曆法,時分看減法」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved