Nó không phải là dễ dàng như nó có vẻ, bởi vì:
1) Ngày chuyển giao giữa DST và giờ chuẩn không giống nhau đối với tất cả các quốc gia
2) Ngày chuyển đổi giữa DST và giờ chuẩn không phải là cùng một thuật toán cho cùng một quốc gia trong tất cả các năm (ví dụ: ở Trung Âu trước đây) Chủ nhật tháng Tư, IIRC, bây giờ là chủ nhật cuối tháng ba). Hoa Kỳ đã thay đổi từ Chủ Nhật đầu tiên vào tháng Tư đến Chủ Nhật thứ hai vào tháng Ba từ năm 2007 trở đi.
Vì vậy - một ngày đơn giản là không đủ, bạn cũng sẽ cần vị trí địa lý.
Nhưng, nếu bạn có thể sống với thực tế, rằng bạn giới hạn mình vào ngày chuyển giao có thể được tính từ HIỆN thuật toán cho HIỆN năm cho HIỆN locale (quốc gia) và rằng đây có thể sai cho những ngày cả hai trong tương lai và trong quá khứ, sau đó bạn có thể sử dụng thông tin trong TIME_ZONE_INFORMATION để tính toán số ngày chuyển giao:
USES Windows,SysUtils,DateUtils;
FUNCTION GetDaylightSavingsSwitchOverDates(Year : Cardinal ; VAR Start,Stop : TDateTime) : BOOLEAN;
VAR
TZ : TTimeZoneInformation;
FUNCTION DecodeSwitchOverDate(Year : Cardinal ; CONST Time : TSystemTime) : TDateTime;
VAR
I : Cardinal;
BEGIN
Result:=EncodeDateTime(Year,Time.wMonth,1,Time.wHour,Time.wMinute,Time.wSecond,0);
IF Time.wDay=5 THEN BEGIN
Result:=DateOf(EndOfTheMonth(Result))+TimeOf(Result);
WHILE PRED(DayOfWeek(Result))<>Time.wDayOfWeek DO
Result:=IncDay(Result,-1)
END
ELSE BEGIN
WHILE PRED(DayOfWeek(Result))<>Time.wDayOfWeek DO Result:=IncDay(Result);
FOR I:=1 TO PRED(Time.wDay) DO Result:=IncWeek(Result)
END
END;
BEGIN
IF GetTimeZoneInformation(TZ)=TIME_ZONE_ID_UNKNOWN THEN
Result:=FALSE
ELSE BEGIN
Start:=DecodeSwitchOverDate(Year,TZ.DaylightDate);
Stop:=DecodeSwitchOverDate(Year,TZ.StandardDate);
Result:=TRUE
END
END;
FUNCTION StartOfDST(Year : Cardinal) : TDateTime;
VAR
Stop : TDateTime;
BEGIN
IF NOT GetDaylightSavingsSwitchOverDates(Year,Result,Stop) THEN Result:=0
END;
FUNCTION EndOfDST(Year : Cardinal) : TDateTime;
VAR
Start : TDateTime;
BEGIN
IF NOT GetDaylightSavingsSwitchOverDates(Year,Start,Result) THEN Result:=0
END;
Looping qua các năm 2000-2020 trên máy tính của tôi (Múi giờ Trung Âu), tôi nhận được các ngày sau:
DST in 2000: Sun 26 Mar 2000 02:00:00 through Sun 29 Oct 2000 03:00:00
DST in 2001: Sun 25 Mar 2001 02:00:00 through Sun 28 Oct 2001 03:00:00
DST in 2002: Sun 31 Mar 2002 02:00:00 through Sun 27 Oct 2002 03:00:00
DST in 2003: Sun 30 Mar 2003 02:00:00 through Sun 26 Oct 2003 03:00:00
DST in 2004: Sun 28 Mar 2004 02:00:00 through Sun 31 Oct 2004 03:00:00
DST in 2005: Sun 27 Mar 2005 02:00:00 through Sun 30 Oct 2005 03:00:00
DST in 2006: Sun 26 Mar 2006 02:00:00 through Sun 29 Oct 2006 03:00:00
DST in 2007: Sun 25 Mar 2007 02:00:00 through Sun 28 Oct 2007 03:00:00
DST in 2008: Sun 30 Mar 2008 02:00:00 through Sun 26 Oct 2008 03:00:00
DST in 2009: Sun 29 Mar 2009 02:00:00 through Sun 25 Oct 2009 03:00:00
DST in 2010: Sun 28 Mar 2010 02:00:00 through Sun 31 Oct 2010 03:00:00
DST in 2011: Sun 27 Mar 2011 02:00:00 through Sun 30 Oct 2011 03:00:00
DST in 2012: Sun 25 Mar 2012 02:00:00 through Sun 28 Oct 2012 03:00:00
DST in 2013: Sun 31 Mar 2013 02:00:00 through Sun 27 Oct 2013 03:00:00
DST in 2014: Sun 30 Mar 2014 02:00:00 through Sun 26 Oct 2014 03:00:00
DST in 2015: Sun 29 Mar 2015 02:00:00 through Sun 25 Oct 2015 03:00:00
DST in 2016: Sun 27 Mar 2016 02:00:00 through Sun 30 Oct 2016 03:00:00
DST in 2017: Sun 26 Mar 2017 02:00:00 through Sun 29 Oct 2017 03:00:00
DST in 2018: Sun 25 Mar 2018 02:00:00 through Sun 28 Oct 2018 03:00:00
DST in 2019: Sun 31 Mar 2019 02:00:00 through Sun 27 Oct 2019 03:00:00
DST in 2020: Sun 29 Mar 2020 02:00:00 through Sun 25 Oct 2020 03:00:00
nhưng ít nhất một số năm này không chính xác do thuật toán đã thay đổi từ ngôn ngữ của tôi trong những năm được liệt kê.
Chức năng của bạn sau đó sẽ là:
FUNCTION IsDaylightSavingTime(Input : TDateTime) : BOOLEAN;
VAR
Start,Stop : TDateTime;
BEGIN
Result:=GetDaylightSavingsSwitchOverDates(YearOf(Input),Start,Stop) AND (Input>=Start) AND (Input<Stop)
END;
tại sao không cập nhật từ xml hoặc cơ sở dữ liệu? có thể dịch vụ web? – none