- Introduction
- Features
- Installation
- Usage
- Common Examples
- Important Considerations
- Updating TZDB
- Tools
- License
TZDB is an offline, in-process compiled database for IANA's TZDB project. It provides reliable time zone conversion and calculation capabilities without requiring external services or runtime dependencies.
The current version is compiled with 2025b version of IANA TZDB and the latest Windows alias translation table (from CLDR project).
The source code is compatible with Delphi XE+ and FreePascal 3+, though some components are only available for Delphi.
đź“š API Documentation | đź’» Code Examples
- Offline operation: No network dependencies or external services required
- Small footprint: Single-file implementation with pre-compiled TZDB database
- Windows alias support: Easily convert between Windows time zone names and IANA identifiers
- Comprehensive API: Rich set of methods for time zone conversions and calculations
- Pure Pascal implementation: No external dependencies or DLLs
Download TZDB.pas and add it to your project.
git submodule add https://github.com/pavkam/tzdb.git
Simply include the TZDB unit in your uses
clause:
uses TZDB;
uses TZDB;
var
LTimeZone: TBundledTimeZone;
begin
// Get time zone by IANA identifier
LTimeZone := TBundledTimeZone.GetTimeZone('Africa/Cairo');
// Convert local time to UTC
WriteLn(LTimeZone.ToUniversalTime(Now));
end;
uses TZDB;
var
LTimeZone: TBundledTimeZone;
begin
// Get time zone by Windows identifier
LTimeZone := TBundledTimeZone.GetTimeZone('Eastern Standard Time');
// Display information
WriteLn('IANA ID: ', LTimeZone.ID);
WriteLn('Current offset: ', LTimeZone.UtcOffset);
end;
uses TZDB;
var
LTimeZone: TBundledTimeZone;
LLocalTime: TDateTime;
LTimeType: TLocalTimeType;
begin
LTimeZone := TBundledTimeZone.GetTimeZone('America/New_York');
LLocalTime := EncodeDate(2023, 11, 5) + EncodeTime(1, 30, 0, 0); // Fall DST transition
// Check what type of local time this is
LTimeType := LTimeZone.GetLocalTimeType(LLocalTime);
case LTimeType of
lttInvalid: WriteLn('This time does not exist (skipped during DST start)');
lttAmbiguous: WriteLn('This time is ambiguous (occurs twice during DST end)');
lttStandard: WriteLn('This is a standard time');
lttDaylight: WriteLn('This is a daylight saving time');
end;
end;
Issue | Description | Handling |
---|---|---|
Invalid IDs | Unknown time zone IDs cause exceptions | TBundledTimeZone.Create throws ETimeZoneInvalid |
Year range | The database covers a limited year range | Methods may throw EUnknownTimeZoneYear for dates outside coverage |
Ambiguous times | During DST→Standard transitions, some hours occur twice | Use AForceDaylight parameter to control interpretation |
Invalid times | During Standard→DST transitions, some hours are skipped | Handle ELocalTimeInvalid exceptions or check with GetLocalTimeType |
Daylight support | Not all time zones have daylight saving time | Use HasDaylightTime to check before DST operations |
Multiple periods | Some zones have multiple DST periods in a year | Don't assume a single daylight/standard transition per year |
Dynamic properties | Display names and offsets change throughout the year | Don't rely on DisplayName , Abbreviation , or UtcOffset as constants |
This project follows IANA releases closely, typically with a 1-2 week delay.
To update manually:
- Use the update-compile.sh script
- Run under MacOS, Linux, or Windows WSL
- Requires Free Pascal compiler
A development tool to display time zone details (Windows only):
This project is available under MIT License.