Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Leap second coming up. Check your date handling code

by 1nickt (Canon)
on Dec 25, 2016 at 21:18 UTC ( [id://1178487]=perlmeditation: print w/replies, xml ) Need Help??

Hi all,

A friendly reminder that a leap second will be added to the clock at the end of 2016. If you do date math at all, you may want to check that your date handling code is ready for it.

For example, versions of DateTime below 1.34 won't handle it correctly:

$ perl -MDateTime -E 'say $DateTime::VERSION' 1.33 $ perl -MDateTime -E ' my $dt = DateTime->new( time_zone => "UTC", year => 2016, month => 12, day => 31, hour => 23, minute => 59, second => 60 ); say $dt->datetime; $dt->add( months => 1 ); say $dt->datetime; ' Invalid second value (60) at -e line 2.
$ perl -MDateTime -E 'say $DateTime::VERSION' 1.39 $ perl -MDateTime -E ' my $dt = DateTime->new( time_zone => "UTC", year => 2016, month => 12, day => 31, hour => 23, minute => 59, second => 60 ); say $dt->datetime; $dt->add( months => 1 ); say $dt->datetime; ' 2016-12-31T23:59:60 2017-02-01T00:00:00

Hope this helps somebody :-)


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re: Leap second coming up. Check your date handling code
by pme (Monsignor) on Dec 26, 2016 at 00:50 UTC
Re: Leap second coming up. Check your date handling code
by choroba (Cardinal) on Dec 26, 2016 at 20:51 UTC
    Note that Google (and others) solves the problem by "smearing" the leap second:

    Business Insider Article

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      I read about that(1), and I hate it!

      As linked to by pme, the official statement from the INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS) reads:

      A positive leap second will be introduced at the end of December 2016. The sequence of dates of the UTC second markers will be: 2016 December 31, 23h 59m 59s 2016 December 31, 23h 59m 60s 2017 January 1, 0h 0m 0s

      In spite of "American exceptionalism" (cough, cough), neither Google, nor Akamai, nor Microsoft, nor Bloomberg, owns science. The international scientific community decided in 1972 that the correct thing to do was to add a second periodically, as is done with the leap day quadrennially. Google's and other companies' decision to employ "smearing" because it's more convenient for them undercuts scientific authority (last thing we need these days!), privatizes reality, and not least, makes their clocks unreliable for 20 hours or more.

      Support science! Say "no" to Google's Not Time Protocol! Stick to pool.ntp.org -- it's open source, community-based, used by many millions of servers, accurate, and written in Perl :-)


      1 (Although not in "Business Insider," which must be owed something by Google, since its articles dominate the Google News selections, even though behind a pay wall if one uses an ad blocker ...)


      The way forward always starts with a minimal test.

        Google's post on this topic is here, but they're not pressuring anyone to use their smeared time -- they are just making the public aware of how they're handling the leap second by 'smearing' the additional second over a 20 hour window centered on midnight.

        They've also posted about how other organizations are doing their smear: UTC-SLS is using a one thousand second smear before the leap, Bloomberg is using a two thousand second smear after the leap, and Akamai, Microsoft and Akamai are doing a 24-hour smear.

        I believe for most consumers of ntp data this smearing is mostly of academic interest. Use whichever time feed is appropriate to you.

        Alex / talexb / Toronto

        Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      So instead of one leap second they do 72000 times a 13.8 leap microseconds?

      Is this really safe?

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

        It all depends on what you're using "time" for and what you're using as your ground truth.

        As far as I understand, Google uses synchronized time for lots stuff like of query ordering and vector clocks etc and it is important for them to have one ground truth up to the point that they install their own GPS clocks in datacenters. As these are mostly for the use by Google, it's up to them to decide how they will handle the additional second, and I can understand from a risk assessment point of view that it's likely less risk to have slightly longer seconds instead of having one additional second with the number 60 and auditing your code for the parts where that becomes relevant.

        The situation becomes interesting when the private use/decision of Google leaks out into the real world for (say) Google Cloud Engine users or whoever else relies on Google infrastructure and timekeeping.

        Personally I can't imagine situations where the exact and synchronized duration of a second is important to you but you don't have your own synchronized clock(s), but you'll have to be prepared for an apparent one second gap when comparing the timestamps of Google infrastructure with the timestamps of your own infrastructure, and over time, the two kinds of timestamps will diverge until at 2017-01-01 00:00:00Z where they will suddenly converge again.

        If this is your first time dealing with diverging clocks, it will be an interesting learning experience, especially if you did to GPS-based time exactly to avoid this situation.

        I don't know if it's relevant, but it occurred to me that RTC crystals used in embedded systems are tuned by manufacturers to operate at the very specific frequency of 32.768kHz. If I recall the original reasoning was that the MSB of a 16-bit counter value toggles every 1 sec for that frequency, and now I'm guessing it's just kind of legacy that it continues to be done that way instead of going to some faster multiple of that value (which would mean physically smaller crystals, less material, board space, etc.). Kind of a moot point since modern technology tends to move away from traditional RTC crystals anyway, but I digress.

        I mention the above because the period for the 32.768kHz frequency is about 30.5 microseconds, so the choice of 20 hours for the smear could have been as arbitrary as the number of hours necessary to reach less than half that value? Technically 19 hours would have been enough, but who likes odd numbers? Besides, us silly engineers have this always add in a margin of error habit even in the digital/discrete realms where we know darn well it doesn't matter. Granted, I'm completely speculating on the reason for the 20 hour smear, I could be totally wrong, I have no inside knowledge or anything like that.

        Just another Perl hooker - Yes, I'll do really dirty code, but I charge extra.
Re: Leap second coming up. Check your date handling code (bad theory)
by tye (Sage) on Dec 27, 2016 at 17:28 UTC

    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        

      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        

      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.
Re: Leap second coming up. Check your date handling code
by perldigious (Priest) on Dec 27, 2016 at 14:50 UTC

    Y2.01700000003171K... Very roughly rounded of course... In fact so roughly rounded that using that exact decimal year value for a second it would lead to over 3 minutes of time slip each year.

    Does anybody else wish we didn't have such an odd time keeping system and instead had something more base 10 like for everything? Not that the Earth's rotation still wouldn't slow and that we wouldn't have to adjust, just something I often wish was true similar to what I wish anytime I have to work in English units (American Exceptionalism indeed). Why couldn't God have created the world in 10 days and spent every other day resting, or maybe just been a prolific procrastinator? I tell you it's like the workaholics in the office that make everybody else look bad for having a life outside of work. :-)

    On a tangentially related note, thanks to Christmas Eve and Christmas both falling on Saturday and Sunday my company gave all us salaried folk one less paid holiday off day this year than is typical. That just makes me feel like spending an entire day posting unproductive stuff like this on PerlMonks, but I'm obviously not one of those workaholics, though I admit I used to be at the beginning of my career before I came to the sad realization that being Boxer from Animal Farm isn't who I wanted to be (so much unpaid overtime I'm never getting back, sigh).

    Just another Perl hooker - Yes, I'll do really dirty code, but I charge extra.
      60 can be divided by 1, 2, 3, 4, 5, 6 and 10. Because of this, you can avoid many fractions.

      perl -E 'for $i (1..10){say "60/$i=".(60/$i)}'

      Same goes for 360 perl -E 'for $i (1..360){say "360/$i=".($_=360/$i)unless(($_=360/$i)-int($_))}'

      Now, base 10 time is not a new concept: metric time. It does take some time to get used to, though. (but at least you will not be ruled by Babylonian time anymore)

      Speaking of Integers: I feel bad for you, son. I got .99999999 problems, and a float ain't one......

        Huh, I learned something today. Kudos, and despite the handy even division by the first 6 natural numbers, metric time still sounds pretty appealing to me if we had jumped on it a lot sooner in human history (pre-industrial revolution would have been nice). Our current physical measurement definitions for so many units being based on seconds having to be changed would be a massive shock to the system Système Internationale. I don't mind floats, but I don't want to get in to a pointed argument... :-)

        Mmm, delicious nostalgia.

        Just another Perl hooker - Yes, I'll do really dirty code, but I charge extra.
Re: Leap second coming up. Check your date handling code
by Linicks (Scribe) on Dec 29, 2016 at 20:44 UTC

    Many years ago, when I was first on the web, there was a lot of perl code going around by a person which I will call Matt Wrong.

    Roll on the year 2000. All of a sudden, a lot of perl coded forums (and such) displayed the year as 19100.

    Of course, the reason was the '19' was hard coded and the tenary years was a counter... the counter reached 100... ha ha.

    Great times. On slashdot a few years later was a post on what the 2000's should be called (i.e. swingng sixties, etc..). I suggested the '19100's' which got a lot of feedback

    So, the moral of this story is let the system do the work - why code your own time stuff?

    $date=`date`; *

    ... and then fiddle with it.

    Nick

    * man date

      So, the moral of this story is let the system do the work - why code your own time stuff?
      $date=`date`; *
      ... and then fiddle with it.

      Assuming date works correctly.

      Back at the turn of 2000, where I worked (then), we had a few legacy apps that were dependent on older versions of Unix. On those systems, the date command started displaying the year as 19100. This was because the systems were old enough that the code (in the date command) that converted the epoch time still didn't account for extracting more than 2 digits worth of year from the epoch time. And, of course, the year was formatted with "19%d", thus the "19100" result.

      So, whatever command - or CPAN module - you use, make sure it actually works for your needs.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1178487]
Approved by atcroft
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 15:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found