Handling Cross-Platform Time Zones
One common problem when handling dates and times, is that time is shown and entered as local, whereas the computer should better use non-geographic information - especially on a Client-Server architecture, where both ends may not be on the same physical region.
A time zone is a region that observes a uniform standard time for
legal, commercial, and social purposes.
Time zones tend to follow the boundaries of countries and their subdivisions because it is convenient for areas in close commercial or other communication to keep the same time.
Most of the time zones on land are offset from Coordinated Universal Time (UTC) by a whole number of hours, or minutes.
Even worse, some countries use daylight saving time for part of the year, typically by changing clocks by an hour, twice every year.
The main rule is that any date and time stored should be stored in
UTC, or with an explicit Zone identifier (i.e. an explicit offset to
the UTC value).
Our framework expects this behavior: every date/time value stored and handled by the ORM, SOA, or any other part of it, is expected to be UTC-encoded.
At presentation layer (e.g. the User Interface), conversion to/from local times should take place, so that the end-user is provided with friendly clock-wall compatible timing.
As you may guess, handling time zones is a complex task, which should be
managed by the Operating System itself.
Since this cultural material is constantly involving, it is updated as part of the OS.
In practice, current local time could be converted from UTC from the current system-wide time zone. One of the only parameters you have to set when installing an Operating System is to pickup the keyboard layout... and the current time zone to be used. But in a client-server environment, you may have to manage several time zones on the server side: so you can't rely on this global setting.
One sad - but predictable - news is that there is no common way of encoding
time zone information.
Under Windows, the registry contains a list of time zones, and the associated time bias data. Most POSIX systems (including Linux and Mac OSX) do rely on the IANA database, also called
tzdata - you may
have noticed that this particular package is often updated with your
Both zone identifiers do not map, so our framework needed something to be shared on all systems.
SynCommons.pas unit features the
class, which is able to retrieve the information from the Windows
registry into memory via
TSynTimeZone.LoadFromRegistry, or into a
compressed file via
Later on, this file could be reloaded on any system, including any Linux flavor, via
TSynTimeZone.LoadFromFile, and returns
the very same results.
The compressed file is pretty small, thanks to its optimized layout, and use of our
SynLZ compression algorithm: the full information is stored in
a 7 KB file - the same flattened information as JSON is around 130 KB, and you
may compare with the official http://www.iana.org content, which weighted as a
tar.gz... Of course,
tzdata stores potentially
a lot more information than we need.
In practice, you may use
TSynTimeZone.Default, which would
return an instance read from the current version of the registry under
Windows, and would attempt to load the information named after the
executable file name (appended as a
.tz extension) on other
You may therefore write:
aLocalTime := TSynTimeZone.Default.NowToLocal(aTimeZoneID);
Similarly, you may use
TSynTimeZone.LocalToUtc methods, with the proper
You would have to create the needed
.tz compressed file under a
Windows machine, put this file together with any Linux server
On a cloud-like system, you may store this information in a centralized server, e.g. via a dedicated service - see Client-Server services via interfaces - generated from a single reference Windows system.
The main benefit is that the time information would stay consistent whatever system it runs on.
Your User Interface could retrieve the IDs and ready to be displayed text
properties, as plain
TStrings instance, which index would follow
TSynTimeZone.Zone internal information.
As a nice side effect, the
TSynTimeZone binary internal storage
has been found out to be very efficient, and much faster than a manual reading
of the Windows registry. Complex local time calculation could be done
on the server side, with no fear of breaking down your processing