[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