Wednesday, May 22, 2013

Get UTC time in Delphi

Many kinds of applications deal with UTC time (http://en.wikipedia.org/wiki/Coordinated_Universal_Time). But Delphi has no buil-in UTC functions. But we can use the Windows function TzSpecificLocalTimeToSystemTime. Let's create simple example in Delphi.
Place a timer, give it a name "UTCTimer" (set interval 200-300 ms), place a label with name "CurrentUTCTimeLabel" on the form.


 var
  MainForm: TMainForm;

implementation

{$R *.dfm}

function TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation: PTimeZoneInformation;
  var lpLocalTime, lpUniversalTime: TSystemTime): BOOL; stdcall; external kernel32 name 'TzSpecificLocalTimeToSystemTime';
{$EXTERNALSYM TzSpecificLocalTimeToSystemTime}

function SystemTimeToUTC(Sys : TDateTime):TDateTime;
var TimeZoneInf : _TIME_ZONE_INFORMATION;
    SysTime,LocalTime: TSystemTime;
begin
  if GetTimeZoneInformation(TimeZoneInf) < $FFFFFFFF then
  begin
    DatetimetoSystemTime(Sys, SysTime);
    if TzSpecificLocalTimeToSystemTime(@TimeZoneInf,SysTime,LocalTime) then
      result:=SystemTimeToDateTime(LocalTime)
    else result:=Sys;
  end else result:=Sys;
end;

// Example of usage UTC

function ZeroNumber(Num: Integer): String;
begin
  if Month < 10 then
    Result := '0' + IntToStr(Num)
  else
    Result := IntToStr(Num);
end;

procedure TMainForm.UTCTimerTimer(Sender: TObject);
var
  Day, Month, Year: Word;
  Hour, Minute, Sec, Millisec: Word;
  UTC: TDateTime;
begin
  UTC := SystemTimeToUTC(Now);
  DecodeDate(UTC, Year, Month, Day);
  DecodeTime(UTC, Hour, Minute, Sec, Millisec);
  CurrentUTCTimeLabel.Caption := ZeroNumber(Day) + '.' + ZeroNumber(Month) + '.' + IntToStr(Year)
    + ' ' + ZeroNumber(Hour) + ':' + ZeroNumber(Minute) + ':' + ZeroNumber(Sec);
end;


Finally we have the following UTC timer: