Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re: Leap second coming up. Check your date handling code (bad theory)

by tye (Sage)
on Dec 27, 2016 at 17:28 UTC ( [id://1178530] : note . print w/replies, xml ) Need Help??

in reply to Leap second coming up. Check your date handling code

Leap seconds don't impact epoch time calculations. So I'd like to see how you, in theory, get a value of '60' for the seconds that you want to pass to something like you've shown. Code that wants to know how many seconds past the start of the current minute is first going to get 'now' as a single number of epoch seconds and then use that to ask for a list of numbers including that number of seconds past the start of the minute. Such code will never have to deal with that last number being 60.

So, for those complaining about the sloppy way that some have chosen to deal with leap seconds of smearing the 1-second jump in are being silly. Because if you don't do that, all that happens in that the 1-second jump happens more sloppily. That is, if you don't smear the leap second out, then you get the exact same value for the epoch seconds for a duration of 2 seconds! Things get worse if you ask for a high-resolution real-time clock value, likely involving your epoch seconds moving backward in time.

- tye        

  • Comment on Re: Leap second coming up. Check your date handling code (bad theory)

Replies are listed 'Best First'.
Re^2: Leap second coming up. Check your date handling code (reality)
by 1nickt (Canon) on Dec 27, 2016 at 21:54 UTC

    Well, hold on there a second, tye, that code is demonstration code, taken, as a matter of fact, from the DateTime docs, and only intended to show whether a library is broken or not.

    You're quite right that it's unlikely you'd pass a value of 60 for seconds as part of a time string. (However, you might be given it as part of one, if you are reading UTC.)

    The rather obvious way you would get bitten is when your program checks to see whether the next second after the current second is a new day. If your date handling code isn't up to, um, date, your program will tell you that it's January 1, 2017, one second before it really is, because it doesn't know to wait a sec.

    $ perl -MDateTime -E ' say $DateTime::VERSION; say DateTime->from_epoch( epoch => 1483228800 )->datetime; say DateTime->from_epoch( epoch => 1483228799 )->add( seconds => 1 )-> +day; ' 1.33 2017-01-01T00:00:00 1
    $ perl -MDateTime -E ' say $DateTime::VERSION; say DateTime->from_epoch( epoch => 1483228800 )->datetime; say DateTime->from_epoch( epoch => 1483228799 )->add( seconds => 1 )-> +day; ' 1.39 2017-01-01T00:00:00 31

    Hope this helps!

    The way forward always starts with a minimal test.

      Well, if you do your duration calculations in that manner, then you are going to have to deal with getting a different answer depending on when you do the calculation (and when you upgrade the list of leap seconds).

      I recommend not doing duration calculations in a manner that tries to account for leap seconds as I find a duration being slightly "off" (from some perspectives that might not actually apply to your system) when it crosses the year boundary of certain rare years to be better than having answers change. Similarly, I also prefer having epoch seconds progress very smoothly rather than having them stutter around a leap second (unless I'm doing some pretty unusual types of processing that likely wouldn't be done based on some Unix/Windows system real-time clock anyway).

      I routinely see time measurements being off by much more than 1 second simply because hardware clocks are reasonably variable and NTP infrastructure is very often not given so much attention that it is kept operating so well that clocks are always kept within less than 1 second of true.

      In fact, I recommend doing duration calculations not using real-time clock data at all, if possible. It is usually much better to do duration calculations based on a high-resolution monotonic clock (but such isn't always possible).

      Now, if you are programming an atomic clock or a GPS system, then you certainly need to account for leap seconds, but you won't be using DateTime either. Now, you might be using DateTime to process high-resolution UTC times logged from some external high-precision clock such as for some astronomy work. In such a case, you want to make sure you have knowledge of new leap seconds in place before those leap seconds happen and then need that data processed, of course.

      But warning people about keeping their Perl infrastructure updated because a new leap second is coming in such a general manner is most likely to lead to more confusion than enlightenment for most people -- who both don't understand the practical impact of leap seconds well and don't realize that they pretty much don't matter for any of their work anyway. In the tons of date/time-handling code that I've worked with over about the last decade, none of it is impacted at all by leap seconds (because I'm not working on astronomy software that deals with high-resolution external clocks that output real-time values).

      Though, I work with tons of systems that claim to be using UTC. This can partly be blamed on fashion and such systems should likely be switched to GMT so that they stop lying about the types of real-time values they are working with. Until you've made such a switch, then accounting for leap seconds is more likely to cause problems than to improve accuracy (and once you've made that switch, the leap seconds won't matter).

      - tye        

Re^2: Leap second coming up. Check your date handling code (bad theory)
by RonW (Parson) on Jan 04, 2017 at 23:22 UTC

    Back when I was still a teen, I worked (part time) for a small company that had to rely on dial-up modems for internet service. Synchronizing time between the office and the factory (several miles apart) had to be done using WWV radios. We had a simple program (in C) that compared the result of gmtime(time(NULL)) with the time string from the WWV radio, then used adjtime() to "nudge" the system clock as needed.

    When a leap second occurred, this "smeared" the extra (or missing) second over the next several minutes, resulting in a gentle transition. (On system boot, though, the time was simply set.)

    Within each building, the computers were able to sync to the building's "master" time keeper over Ethernet.

    Because I was curious - and the office was on a high enough floor to be able to see the factory buildings - I setup a laser and aimed it at the window of a room in one of the factory buildings. I wired a circuit to a serial port on a computer in the office and to the modulation input of the laser. Then I went to the factory and plugged an optical receiver (I built) into a serial port on a computer, there. Then I ran a shell script to alternately read/display a line from the serial and run the date command. The time on both computers was definitely within 1 second of each other. Probably within .1 second.

      This post is glorious, and it made my day reading it because I'm laughing and thinking about all the stories like this my Electronics Engineer colleagues have told me over the years.

      Back when I was still a teen... Because I was curious... I setup a laser... I wired a circuit to a... computer... and to the modulation input of the laser... an optical receiver (I built)...

      The further I read the more I laughed and thought of this.

      Just another Perl hooker - Yes, I'll do really dirty code, but I charge extra.