Convert TDateTime to Another Time Zone Regardless of Local Time Zone

后端 未结 3 1246
庸人自扰
庸人自扰 2021-02-10 23:53

Regardless of what the user\'s local time zone is set to, using Delphi 2007, I need to determine the time (TDateTime) in the Eastern time zone.

How can I do that? Of co

3条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-11 00:13

    If I understand you correctly, you want the Eastern Time equivalent of the current system time.

    To do this, use the WiNAPI function GetSystemTime() to get the current time of the computer in UTC. UTC is independent of time zones and will always get you the time at the prime meridian.

    You can then use the WinAPI function SystemTimeToTzSpecificLocalTime() to calculate the local time in any other given time zone from the UTC time. In order that SystemTimeToTzSpecificLocalTime() can work, you need to give it a TTimeZoneInformation record that is populated with the correct information for the time zone you want to convert to.

    The following sample will always gives you the local time in Eastern Time as per Energy Policy Act of 2005.

    function GetEasternTime: TDateTime;
    var
      T: TSystemTime;
      TZ: TTimeZoneInformation;
    begin
      // Get Current time in UTC
      GetSystemTime(T);
    
      // Setup Timezone Information for Eastern Time
      TZ.Bias:= 0;
    
      // DST ends at First Sunday in November at 2am
      TZ.StandardBias:= 300;
      TZ.StandardDate.wYear:= 0;
      TZ.StandardDate.wMonth:= 11; // November
      TZ.StandardDate.wDay:= 1; // First
      TZ.StandardDate.wDayOfWeek:= 0; // Sunday
      TZ.StandardDate.wHour:= 2;
      TZ.StandardDate.wMinute:= 0;
      TZ.StandardDate.wSecond:= 0;
      TZ.StandardDate.wMilliseconds:= 0;
    
      // DST starts at Second Sunday in March at 2am
      TZ.DaylightBias:= 240;
      TZ.DaylightDate.wYear:= 0;
      TZ.DaylightDate.wMonth:= 3; // March
      TZ.DaylightDate.wDay:= 2; // Second
      TZ.DaylightDate.wDayOfWeek:= 0; // Sunday
      TZ.DaylightDate.wHour:= 2;
      TZ.DaylightDate.wMinute:= 0;
      TZ.DaylightDate.wSecond:= 0;
      TZ.DaylightDate.wMilliseconds:= 0;
    
      // Convert UTC to Eastern Time
      Win32Check(SystemTimeToTzSpecificLocalTime(@TZ, T, T));
    
      // Convert to and return as TDateTime
      Result := EncodeDate(T.wYear, T.wMonth, T.wDay) + 
       EncodeTime(T.wHour, T.wMinute, T.wSecond, T.wMilliSeconds);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Label1.Caption:= 'In New York Citiy, it is now ' + DateTimeToStr(GetEasternTime);
    end;
    

提交回复
热议问题