Jump to content
Ailur

How to get the UTC and the local time values of Now even if DST observation changes? (Atomicity)

Recommended Posts

Hello everyone!

 

Is there a way to make the following routine atomic, so it will yield the correct results even when a switch between standard time/winter time and daylight saving time/summer time happens in the middle of it?

 

uses
  System.DateUtils,
  System.SysUtils;

procedure GetUTCAndLocalNow(var UTC, Local: TDateTime);
begin
  Local := Now;
  UTC := TTimeZone.Local.ToUniversalTime(Local);
end;

 

Ultimately I am looking for the UTC and the local time values to be ISO 8601 formatted strings and I am not bound to TDateTime as given in the above routine.

Edited by Ailur

Share this post


Link to post

Why not get system (UTC) time via GetSystemTime?

Edited by Fr0sT.Brutal
  • Like 1

Share this post


Link to post

I am open to use a different API or data types to get the values. One could say my difficulty lies with getting the correct conversion method that was valid at a past moment in time, even if that moment lies just a few milliseconds back:

procedure GetUTCAndLocalNow(var UTC, Local: TDateTime);
var
  Convert: Func<TDateTime, TDateTime>;
begin
  Local := Now;
  Convert := GetConvertMethodForAPastMomentInTime(Local);
    // ... even if this past moment in time is just some milliseconds ago
    // it might have changed due to a change in DST observation
  UTC := Convert(Local);
end;

 

Share this post


Link to post

If your goal is to achieve consistency between local and UTC times which are milliseconds apart, you should start with the UTC time, not the local time. 

 

Get the UTC time first.  Then use a library such as https://github.com/pavkam/tzdb to derive the local time from it, for the location you require, using the IATA database.  If the UTC time happened to be 01:59:59.998 on a changeover day scheduled at 2am, then this library will return the correct local time for this UTC time and location, even if you call it 5ms later.  The library also has options to select how you want to handle the edge cases if for some reason you have to start, as in your examples, from the local time. Some days, a local time may occur twice or not at all.

 

There may be other ways to do this without an external library, but using the TZDB gives you flexibility to handle different time zones and DST rules. The fact that you ask for millisecond consistency implies that you may require this extra capability.

 

Edited by timfrost

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×