-
Notifications
You must be signed in to change notification settings - Fork 28
Code Examples
Each distribution/version of TZDB contains a fully-compiled version of latest IANA database. To check the version that is included in a specific distribution of TZDB a method DbVersion
is available:
uses TZDB;
begin
WriteLn('This TZDB uses version ', TBundledTimeZone.DbVersion);
end;
The following code retrieves a time zone instance for Europe/Amsterdam
. The instance needs to be freed after use if the constructor is used to create it (rather than the factory method).
var
LAmsterdam: TBundledTimeZone;
begin
LAmsterdam := TBundledTimeZone.Create('Europe/Amsterdam');
...
...
LAmsterdam.Free;
end;
The same example but using a factory method for better caching support. In this case the instance must not be freed since it is cached internally.
var
LAmsterdam: TBundledTimeZone;
begin
LAmsterdam := TBundledTimeZone.GetTimeZone('Europe/Amsterdam');
...
...
end;
The following example simply displays all time zones that are known to TZDB.
var
LTZID: string;
begin
// Write each time zone ID on the console
for LTZID in TBundledTimeZone.KnownTimeZones(true) do
WriteLn(LTZID);
end;
❗️Note that
true
has been passed toKnownTimeZones
method. This parameter controls whether aliases are included into the output. TZDB also includes a large number of aliases for each time zone ID. For exampleAustralia/Darwin
time zone has an alias ofAUS Central Standard Time
(Windows naming); andEtc/GMT+1
has an alias ofGMT+1
. The query operations automatically look up aliases so do not have to worry about them.
The following example shows a simple program that takes an arbitrary local time (in current time zone) and then displays the time as seen in Sydney, Australia
.
var
LSydney: TBundledTimeZone;
LMadeUpLocalTime, LUniversalTime,
LSydneyTime: TDateTime;
begin
// Get the Sydney time zone
LSydney := TBundledTimeZone.GetTimeZone('Australia/Sydney');
// Encode a local date/time value -- 14th March 2009 at 12:45:00 PM
LMadeUpLocalTime := EncodeDateTime(2009, 03, 14, 12, 45, 00, 00);
// Find out what was the time in Sydney at that moment
LUniversalTime := TTimeZone.Local.ToUniversalTime(LMadeUpLocalTime);
LSydneyTime := LSydney.ToLocalTime(LUniversalTime);
WriteLn(Format('When in my time zone the time was %s, in Sydney it was %s.',
[DateTimeToStr(LMadeUpLocalTime), DateTimeToStr(LSydneyTime)]));
end;
The example below shows how to use the GetYearBreakdown
method to calculate the number of days observing the DST.
var
LTZ: TBundledTimeZone;
LSegments: TYearSegmentArray;
LSegment: TYearSegment;
LDays: Integer;
begin
// Get the TZ and break a year into segments.
LTZ := TBundledTimeZone.GetTimeZone('Europe/Paris');
LSegments := LTZ.GetYearBreakdown(2019);
// Iterate all segments to find the DST ones
// (yes, there might be multiple DSTs per year!):
LDays := 0;
for LSegment in LSegments do
begin
if LSegment.LocalType = lttDaylight then
// Calculate the number of days between the start and the of the segment.
Inc(LDays, DaysBetween(LSegment.EndsAt, LSegment.StartsAt));
end;
WriteLn('There are a total of ', LDays, ' DST days in time zone "', LTZ.ID, '".');
end;
The same can be achieved by using a set of helper methods:
var
LTZ: TBundledTimeZone;
LDays: Integer;
begin
// Get the TZ and break a year into segments.
LTZ := TBundledTimeZone.GetTimeZone('Europe/Paris');
// A simpler form that takes care of some complexity but only works
// for simple time zones.
if LTZ.HasDaylightTime(2019) then
LDays := DaysBetween(LTZ.DaylightTimeEnd(2019), LTZ.DaylightTimeStart(2019))
else
LDays := 0;
WriteLn('There are a total of ', LDays, ' DST days in time zone "', LTZ.ID, '".');
end;
❗️Methods such as
DaylightTimeEnd
orStandardTimeStart
etc. are unsafe for serious use as they will fail to account for time zones that have more than one DST.