在報表統計、排程判斷、資料篩選等場景中,我們常需要「某年的第一毫秒」或「某月的最後一秒」。DateUtils 提供了成對的 StartOf… 與 EndOf… 函式,支援以 TDateTime 或數值參數兩種方式調用,精準返回區間邊界。本文將這 16 個函式分類整理,並給出完整測試代碼。
| 粒度 | 數值參數版 (A…) | TDateTime 參數版 (The…) | 說明 |
|---|---|---|---|
| 年 | StartOfAYear(Year)EndOfAYear(Year) | StartOfTheYear(DateTime)EndOfTheYear(DateTime) | 年份邊界 |
| 月 | StartOfAMonth(Year, Month)EndOfAMonth(Year, Month) | StartOfTheMonth(DateTime)EndOfTheMonth(DateTime) | 月份邊界 |
| 週 | StartOfAWeek(Year, WeekOfYear)EndOfAWeek(Year, WeekOfYear) | StartOfTheWeek(DateTime)EndOfTheWeek(DateTime) | 週邊界 (週一為起始) |
| 日 | StartOfADay(Year, DayOfYear)EndOfADay(Year, DayOfYear) | StartOfTheDay(DateTime)EndOfTheDay(DateTime) | 單日邊界 |
BETWEEN 查詢。WeekOfYear 範圍 1~53。StartOfADay/EndOfADay 的數值參數。uses DateUtils;
var
dt, t1, t2, t3, t4: TDateTime;
s1, s2, s3, s4: string;
begin
dt := StrToDateTime('2009-5-20 11:22:33');
// 年
t1 := StartOfAYear(2009); // 2009-1-1 0:0:0:000
t2 := StartOfTheYear(dt); // 2009-1-1 0:0:0:000
t3 := EndOfAYear(2009); // 2009-12-31 23:59:59:999
t4 := EndOfTheYear(dt); // 2009-12-31 23:59:59:999
// 月
t1 := StartOfAMonth(2009, 5); // 2009-5-1 0:0:0:000
t2 := StartOfTheMonth(dt); // 2009-5-1 0:0:0:000
t3 := EndOfAMonth(2009, 5); // 2009-5-31 23:59:59:999
t4 := EndOfTheMonth(dt); // 2009-5-31 23:59:59:999
// 週 (2009 年第 21 週)
t1 := StartOfAWeek(2009, 21); // 2009-5-18 0:0:0:000
t2 := StartOfTheWeek(dt); // 2009-5-18 0:0:0:000
t3 := EndOfAWeek(2009, 21); // 2009-5-24 23:59:59:999
t4 := EndOfTheWeek(dt); // 2009-5-24 23:59:59:999
// 日 (2009 年第 140 天)
t1 := StartOfADay(2009, 140); // 2009-5-20 0:0:0:000
t2 := StartOfTheDay(dt); // 2009-5-20 0:0:0:000
t3 := EndOfADay(2009, 140); // 2009-5-20 23:59:59:999
t4 := EndOfTheDay(dt); // 2009-5-20 23:59:59:999
end;
{ SQL 範圍查詢: 取得本月所有訂單 }
var StartDt, EndDt: TDateTime;
begin
StartDt := StartOfTheMonth(Now);
EndDt := EndOfTheMonth(Now);
Query.SQL.Text := 'SELECT * FROM Orders WHERE OrderDate BETWEEN :S AND :E';
Query.ParamByName('S').AsDateTime := StartDt;
Query.ParamByName('E').AsDateTime := EndDt;
end;
{ 判斷某日期是否為週末 }
function IsWeekend(D: TDateTime): Boolean;
var W: Word;
begin
W := DayOfTheWeek(D); // 1=週一 ... 7=週日
Result := (W = 6) or (W = 7);
end;
善用這組邊界函式,能讓時間區間邏輯更嚴謹、代碼更易讀,避免手動拼湊字串或浮點數運算帶來的邊界誤差。