Конвертировать TDateTime в другой часовой пояс независимо от местного часового пояса - PullRequest
4 голосов
/ 27 марта 2009

Независимо от того, какой локальный часовой пояс пользователя установлен, с помощью Delphi 2007 мне нужно определить время (TDateTime) в восточном часовом поясе.

Как я могу это сделать? Конечно, необходимо учитывать летнее время.

Ответы [ 3 ]

11 голосов
/ 05 мая 2009

Если я вас правильно понимаю, вы хотите, чтобы восточное время соответствовало текущему системному времени.

Для этого используйте функцию WiNAPI GetSystemTime(), чтобы узнать текущее время компьютера в формате UTC. UTC не зависит от часовых поясов и всегда даст вам время на главном меридиане.

Затем можно использовать функцию WinAPI SystemTimeToTzSpecificLocalTime(), чтобы рассчитать местное время в любом другом заданном часовом поясе из времени UTC. Чтобы SystemTimeToTzSpecificLocalTime() мог работать, вам нужно предоставить ему запись TTimeZoneInformation, которая заполнена правильной информацией для часового пояса, в который вы хотите преобразовать.

В следующем примере всегда указывается местное время по восточному времени в соответствии с Законом об энергетической политике 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;
3 голосов
/ 09 апреля 2009

TDateTime не имеет никакой информации о часовом поясе (это просто двойная дата как целое число, время как десятичное), поэтому вам это понадобится отдельно. Вам также понадобится своя логика для DST, я не верю, что она есть в Delphi. Затем используйте функцию IncHour в DateUtils.pas, чтобы изменить TDateTime на восточный часовой пояс.

Возможно, есть веб-сервисы, которые сделают это за вас. Ваше приложение должно быть автономным или оно может подключаться к Интернету?

1 голос
/ 09 апреля 2009

Если быть точным, TDateTime - это не объект, это просто псевдоним для double.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...