[DUG] timezone help

Jeremy Coulter jscoulter at gmail.com
Mon Apr 6 20:44:12 NZST 2009


Ok, well  finally worked it out. I was almost close, but your code helped
out :-)
 
Thanks again.
 
Jeremy

  _____  

From: delphi-bounces at delphi.org.nz [mailto:delphi-bounces at delphi.org.nz] On
Behalf Of Kyley Harris
Sent: 6 April 2009 14:51
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] timezone help


unit uDateTimeGMTConversion;

interface

uses
  Sysutils,
  classes, Windows, uHssShareCommon, uItem;

type


  TDateTimeGMTConversion = class(TObject)
  private
    FZoneType:DWord;
    FTimeZoneInfo: TTimeZoneInformation;
    FForceTimeZone: boolean;
    FForcedTimeZoneInfo: TTimeZoneInformation;

    function GetTimeZoneInfo:TTimeZoneInformation;
  public
    constructor create;

    class procedure ForceLocalTimeZoneIgnoreGMT(AValue:boolean);
    function DateIsDaylight(ADate:TDateTime):boolean;
    function
LocalMachineTimeToGMT(ALocalMachineTime:TDateTime):TDateTime;virtual;
    function GMTToLocalMachineTime(AGMTTime:TDateTime):TDateTime;virtual;

    procedure SetTimeZone(Zone:THssTimeZoneInformation);

    property TimeZoneInfo:TTimeZoneInformation read FTimeZoneInfo;

    property ForceTimeZone:boolean read FForceTimeZone write FForceTimeZone;
    property ForcedTimeZoneInfo:TTimeZoneInformation read
FForcedTimeZoneInfo write FForcedTimeZoneInfo;



  end;

  TTimeZones = class(THssTimeZoneInformations)
  public
    function
GetBIAS(sender:TObject;AItem:TItem;AFieldName:string;AFieldValue:Variant):va
riant;
  end;

  TTimeZoneData = class(THssTimeZoneInformation)
  public
    TimeZoneInformation:TTimeZoneInformation;
  end;

var
  GMTEngine:TDateTimeGMTConversion;
  TimeZones:THssTimeZoneInformations;


var
  ZeroDateThreshold:TDateTime;
implementation

uses DateUtils , Registry;

var
  AForceLocalTimeOnly:boolean=false;

{ TDateTimeGMTConversion }

constructor TDateTimeGMTConversion.create;
begin
  inherited;
  FZoneType := GetTimeZoneInformation(FTimeZoneInfo);
end;

function TDateTimeGMTConversion.DateIsDaylight(ADate: TDateTime): boolean;
var
  y,m,d,h,n,s,z:word;
  TZI:TTimeZoneInformation;
begin
  result := false;
  TZI := GetTimeZoneInfo;

  if (TZI.StandardDate.wMonth = 0) or (TZI.DaylightDate.wMonth = 0) then
    exit;

  DecodeDateTime(ADate,y,m,d,h,n,s,z);
  if TZI.StandardDate.wMonth < TZI.DaylightDate.wMonth then
  begin
    result := not (
        (EncodeDateTime(y,m,d,h,m,s,z) >=
 
EncodeDateTime(y,TZI.StandardDate.wMonth,TZI.StandardDate.wDay,TZI.StandardD
ate.wHour,0,0,0) ) and

        (EncodeDateTime(y,m,d,h,m,s,z) <=
 
EncodeDateTime(y,TZI.DaylightDate.wMonth,TZI.DaylightDate.wDay,TZI.DaylightD
ate.wHour,0,0,0) )
        );
  end else
  begin
    result := (
        (EncodeDateTime(y,m,d,h,m,s,z) >=
 
EncodeDateTime(y,TZI.DaylightDate.wMonth,TZI.DaylightDate.wDay,TZI.DaylightD
ate.wHour,0,0,0) ) and

        (EncodeDateTime(y,m,d,h,m,s,z) <=
 
EncodeDateTime(y,TZI.StandardDate.wMonth,TZI.StandardDate.wDay,TZI.StandardD
ate.wHour,0,0,0) )
        );
  end;

  //  if TZI.StandardDate.wMonth

end;

procedure TDateTimeGMTConversion.SetTimeZone(
  Zone: THssTimeZoneInformation);
begin
  if Zone = nil then
  begin
    ForceTimeZone := false;


  end else
  begin
    Assert(Zone is TTimeZoneData);
    ForceTimeZone := True;
    FForcedTimeZoneInfo := (Zone as TTimeZoneData).TimeZoneInformation;
  end;
end;

function TDateTimeGMTConversion.GetTimeZoneInfo: TTimeZoneInformation;
begin
  if FForceTimeZone then
    result := FForcedTimeZoneInfo else
    result := FTimeZoneInfo;
end;

function TDateTimeGMTConversion.GMTToLocalMachineTime(
  AGMTTime: TDateTime): TDateTime;
begin
  if AGMTTime < ZeroDateThreshold then
  begin
    result := 0.0;
  end else
  begin
    if AForceLocalTimeOnly and (not FForceTimeZone) then
    begin
      result := RecodeMilliSecond(AGMTTime,0);
      exit;
    end;

    result := IncMinute(AGMTTime,GetTimeZoneInfo.Bias * -1);
    if DateIsDaylight(result) then
      result :=  IncMinute(result,GetTimeZoneInfo.DaylightBias * -1);

    result := RecodeMilliSecond(result,0);

  end;
end;

function TDateTimeGMTConversion.LocalMachineTimeToGMT(
  ALocalMachineTime: TDateTime): TDateTime;
begin
  if ALocalMachineTime <= ZeroDateThreshold then
  begin
    result := 0.0;
  end else
  begin
    if AForceLocalTimeOnly and (not FForceTimeZone) then
    begin
      result := RecodeMilliSecond(ALocalMachineTime,0);
      exit;
    end;

    result := IncMinute(ALocalMachineTime,GetTimeZoneInfo.Bias);
    if DateIsDaylight(ALocalMachineTime) then
      result := IncMinute(result,GetTimeZoneInfo.DaylightBias);

    result := RecodeMilliSecond(result,0);

  end;
end;


type
  REGTzInfo = record
    Bias: Longint;
    StandardBias: Longint;
    DaylightBias: Longint;
    StandardDate: TSystemTime;
    DaylightDate: TSystemTime;
  end;

var
  Keys:TStringList;
  i:integer;
  TZ:TTimeZoneData;
  rTZ:REGTzInfo;
class procedure TDateTimeGMTConversion.ForceLocalTimeZoneIgnoreGMT(
  AValue: boolean);
begin
  AForceLocalTimeOnly := AValue;
end;

{ TTimeZones }

function TTimeZones.GetBIAS(sender: TObject; AItem: TItem;
  AFieldName: string; AFieldValue: Variant): variant;
var
  z:TTimeZoneData absolute AITem;
begin
  result := z.TimeZoneInformation.Bias * -1;
end;

initialization
  GMTEngine := TDateTimeGMTConversion.create;

  TimeZones := TTimeZones.Create(nil);

  TimeZones.BeginUpdate;
  with TRegistry.Create(KEY_READ) do
  try
    RootKey := HKEY_LOCAL_MACHINE;
    if OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time
Zones',false) then
    begin
      Keys := TStringList.Create();
      try
        GetKeyNames(Keys);
        CloseKey;
        for i := 0 to Keys.Count -1 do
        begin
          if OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time
Zones\'+Keys[i],false) then
          begin
            TZ := TimeZones.Add(TTimeZoneData) as TTimeZoneData;
            with TZ do
            begin
              Description := ReadString('Std');
              DisplayData := ReadString('Display');
              ReadBinaryData('TZI',rTZ,SizeOf(RegTZInfo)) ;

              TimeZoneInformation.Bias := rtZ.Bias;
              TimeZoneInformation.StandardDate := rtZ.StandardDate;
              TimeZoneInformation.StandardBias := rtZ.StandardBias;
              TimeZoneInformation.DaylightDate := rtZ.DaylightDate;
              TimeZoneInformation.DaylightBias := rtZ.DaylightBias;
            end;
            CloseKey;
          end;

        end;

      finally
        FreeAndNil(Keys);
      end;



    end;

  finally
    Free;
  end;

  TimeZones.EndUpdate;
  TimeZones.NewIndex('BIAS','GETBIAS',TTimeZones (TimeZones).GetBias);


  ZeroDateThreshold := EncodeDate(1901,01,01);
finalization
  FreeAndNil(GMTEngine);
  FreeAndNil(TimeZones);
end.


On Mon, Apr 6, 2009 at 2:44 PM, Jeremy Coulter <jscoulter at gmail.com> wrote:


Hi all.
I want to write something that will take a time in a different timezone and
convert it to another time zone.

i.e. If its say  11pm Sunday in say New York what time is that here in NZ? I
thought of NY since it can be "yesterday" their time.

I have some code that tells me what the GMT offset is for NY, but how do I
calculate the time to NZ time?


Jeremy


_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at delphi.org.nz with Subject:
unsubscribe





-- 
Kyley Harris
Harris Software
+64-21-671-821

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserver.123.net.nz/pipermail/delphi/attachments/20090406/5b7bdf3d/attachment.html 


More information about the Delphi mailing list