Tuesday, March 08, 2016

[kgfcfeje] Experimenting with the leap second using the right timezone database

Using the "right" timezone database, we can get the GNU date utility to emit the magical time 23:59:60, which only occurs at a leap second.

+ TZ=right/UTC date --date=@1435708824
Tue Jun 30 23:59:59 UTC 2015
+ TZ=right/UTC date --date=@1435708825
Tue Jun 30 23:59:60 UTC 2015
+ TZ=right/UTC date --date=@1435708826
Wed Jul  1 00:00:00 UTC 2015

We can also see the __:59:60 time in a different time zone.

+ TZ=right/America/Los_Angeles date --date=@1435708824
Tue Jun 30 16:59:59 PDT 2015
+ TZ=right/America/Los_Angeles date --date=@1435708825
Tue Jun 30 16:59:60 PDT 2015
+ TZ=right/America/Los_Angeles date --date=@1435708826
Tue Jun 30 17:00:00 PDT 2015

In real time (as opposed to artificially specifying the date with the --date option), you would only be able to see if this if you have your computer configured so that the kernel counts the "right" counter, not the POSIX counter.  Nobody does this, because NTP is designed to use the POSIX counter.  (However, if you are willing to observe the leap second happening at the wrong time, then you can observe it as shown above by specifying the "right" timezone database even though your computer uses the POSIX counter.  See below for when the wrong time is, or see this post.)

We can parse a leap second date into a "right" counter value (not POSIX):

+ date '--date=TZ="right/UTC" 2015-06-30 23:59:59' +%s
1435708824
+ date '--date=TZ="right/UTC" 2015-06-30 23:59:60' +%s
1435708825
+ date '--date=TZ="right/UTC" 2015-07-01 00:00:00' +%s
1435708826

The POSIX counter can never get 23:59:60.

+ TZ=posix/UTC date --date=@1435708799
Tue Jun 30 23:59:59 UTC 2015
+ TZ=posix/UTC date --date=@1435708800
Wed Jul  1 00:00:00 UTC 2015

Going in reverse results in an error:

+ date '--date=TZ="posix/UTC" 2015-06-30 23:59:59' +%s
1435708799
+ date '--date=TZ="posix/UTC" 2015-06-30 23:59:60' +%s
date: invalid date 'TZ="posix/UTC" 2015-06-30 23:59:60'
+ date '--date=TZ="posix/UTC" 2015-07-01 00:00:00' +%s
1435708800

When a UTC date is converted to a "right" counter value, then that right counter value is reinterpreted as a POSIX counter, then the POSIX counter converted to a UTC date, the date curiously gets converted to a date in the future.  This provides the "wrong time" that you can observe the leap second.  That is, 25 seconds after the actual occurrence of the leap second, and if your timezone is set to a lie (namely "right/(something)"), you can observe __:59:60.  (The next leap second will come after a delay of 26 seconds from its actual occurrence.)

+ TZ=posix/UTC date '--date=TZ="right/UTC" 2015-06-30 23:59:59'
Wed Jul  1 00:00:24 UTC 2015
+ TZ=posix/UTC date '--date=TZ="right/UTC" 2015-06-30 23:59:60'
Wed Jul  1 00:00:25 UTC 2015
+ TZ=posix/UTC date '--date=TZ="right/UTC" 2015-07-01 00:00:00'
Wed Jul  1 00:00:26 UTC 2015

The same process can be done in reverse, a POSIX counter value reinterpreted as a right counter.

+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01 00:00:24'
Tue Jun 30 23:59:59 UTC 2015
+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01 00:00:25'
Tue Jun 30 23:59:60 UTC 2015
+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01 00:00:26'
Wed Jul  1 00:00:00 UTC 2015

The identity transformation with POSIX counters causes a parsing error.

+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-06-30 23:59:59'
Tue Jun 30 23:59:59 UTC 2015
+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-06-30 23:59:60'
date: invalid date 'TZ="posix/UTC" 2015-06-30 23:59:60'
+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-07-01 00:00:00'
Wed Jul  1 00:00:00 UTC 2015

The identity transformation with right counters is literally the identity.

+ TZ=right/UTC date '--date=TZ="right/UTC" 2015-06-30 23:59:59'
Tue Jun 30 23:59:59 UTC 2015
+ TZ=right/UTC date '--date=TZ="right/UTC" 2015-06-30 23:59:60'
Tue Jun 30 23:59:60 UTC 2015
+ TZ=right/UTC date '--date=TZ="right/UTC" 2015-07-01 00:00:00'
Wed Jul  1 00:00:00 UTC 2015

Specifying the output (outer) TZ variable (as right or posix) has no effect on the returned counter value.

+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:24' +%s
1435708824
+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:25' +%s
1435708825
+ TZ=right/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:26' +%s
1435708826

+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:24' +%s
1435708824
+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:25' +%s
1435708825
+ TZ=posix/UTC date '--date=TZ="posix/UTC" 2015-07-01T00:00:26' +%s
1435708826

No comments :