Saturday, December 31, 2016

[aamtoufg] Observing the leap second (at the wrong time)

First, find out what time the leap second will occur in your local timezone:

$ date '--date=TZ="right/UTC" 2016-12-31 23:59:60'
Sat Dec 31 19:00:26 EST 2016

Then, as that time approaches:

$ TZ=right/EST date

You can substitute right/UTC for right/EST if you wish to see the leap second in UTC.  You can also substitute things like right/America/New_York.

Simulation of what should happen, by artificially setting the date:

$ TZ=right/EST date '--date=TZ="posix/EST" 2016-12-31 19:00:25'
Sat Dec 31 18:59:59 EST 2016
$ TZ=right/EST date '--date=TZ="posix/EST" 2016-12-31 19:00:26'
Sat Dec 31 18:59:60 EST 2016
$ TZ=right/EST date '--date=TZ="posix/EST" 2016-12-31 19:00:27'
Sat Dec 31 19:00:00 EST 2016

Note well, this will mark the leap second some 26 seconds after it actually occurs.  Details of why in the previous post. Also more information about the "right" timezone database.

You may also wish to add --iso=ns (nanoseconds) to date, or wrap the whole thing in a loop:

while true ; do ... ; done

Or add a sleep 1.

Observing the leap second at the wrong time has the benefit that the computer has settled down to a steady state by then, so you won't see additional weird things happening as the leap second actually occurs, as the computer resets its system clock.  One can try something hacky like the following to cause __:59:60 to display at the actual leap second,

$ TZ=right/EST date --date=@$(( $(date +%s) + 27 ))

but the computer behaves weirdly at the actual leap second. The above command will be 1 second too fast before the leap second, hold 18:59:60 for 2 seconds (the latter of which is the actual leap second), then be correct after the leap second.  Changing to +26 will be correct before the leap second, hold 59:59 for 2 seconds (including during the leap second), display 59:60 (1 second after the leap second), then continue to be 1 second slow afterwards.  Here is a simulation of +27:

$ TZ=right/EST date --date=@$(( $(date '--date=TZ="posix/EST" 2016-12-31 18:59:58' +%s) + 27 ))
Sat Dec 31 18:59:59 EST 2016
$ TZ=right/EST date --date=@$(( $(date '--date=TZ="posix/EST" 2016-12-31 18:59:59' +%s) + 27 ))
Sat Dec 31 18:59:60 EST 2016
$ TZ=right/EST date --date=@$(( $(date '--date=TZ="posix/EST" 2016-12-31 19:00:00' +%s) + 27 ))
Sat Dec 31 19:00:00 EST 2016

Another silly hack: if one is going to observe the leap second at the wrong time, then one might as well observe it at local midnight.

$ TZ=right/UTC date --date=@$(( $(date '--date=TZ="posix/EST" 2016-12-31 23:59:59' +%s) + 26 - 18000)) '+%r %Y'
11:59:59 PM 2016
$ TZ=right/UTC date --date=@$(( $(date '--date=TZ="posix/EST" 2017-1-1 0:00:00' +%s) + 26 - 18000)) +'%r %Y'
11:59:60 PM 2016
$ TZ=right/UTC date --date=@$(( $(date '--date=TZ="posix/EST" 2017-1-1 0:00:01' +%s) + 26 - 18000)) '+%r %Y'
12:00:00 AM 2017

The following script will try to tick the seconds at the correct time with subsecond precision:

while true ; do while [[ $(date +%N) > 090000000 ]] ; do : ; done ; TZ=right/UTC date --date=@$(( $(date +%s) + 26 - 18000)) '+%r %Y' ; sleep 0.9 ; done

Update: Some actual observations.

No comments :