Joshua Hoblitt wrote: >Entirely accidental, I assure you! Oh dear.
There are two fundamental problems with DateTime's handling of leap seconds: one pertaining to the future, and one pertaining to the past. For future times, DateTime implicitly assumes that there will never be another leap second. This assumption is incorrect. It is fundamental to the definition of UTC that more leap seconds will be announced from time to time. It is impossible to have a complete list of leap seconds. DateTime's assumption that its leap second list is complete is so fundamentally incorrect that I took it to be a deliberate design decision. Unknown leap seconds are quite a complication in dealing with future dates: ignoring them is a possible way to cope, but not one that I recommend. For past times, DateTime has a time-of-day model where the same time scale which contains leap seconds extends infinitely far backwards with no leaps before 1972. UTC actually had leaps (but not of whole seconds), and a variable rate, prior to 1972, going back to 1961. Prior to 1961 there is no UTC. An accurate representation of UTC can't do anything with times earlier than 1961, or 1972 if its scope is limited to the leap second version. So it's not clear what time scale you intend to use prior to 1972. Once again I took it to be a design decision to fudge the issue and invent a time scale of convenience. >But you know this as you've had to implement leapseconds in >Time::UTC too. Yes. I grok UTC. I'm also on the mailing list discussing the future of leap seconds, btw. Debate has raged there for several years with no conclusion in sight. Recently there's been some ontological discussion that might form a basis on which to frame the debate properly. I think we'll need some similar work on ontology here if DateTime is to have a more sophisticated concept of time-of-day. >Uh, what about the ->jd() & ->mjd() DateTime.pm methods? Mmm. There's a trivial issue that they're subject to floating point rounding which limits the resolution to about 80 us. And a not-quite-so-trivial issue that the structure of the floating point operations is liable to introduce errors from multiple rounding. The biggie, though, is the handling of leap seconds. JDs don't really work properly with UTC, of course, so having a ->jd method without further explanation, when you have a UTCish time-of-day model, seems unwise. There is no tradition (AFAIK) of calculating the fractional JD the way you do, with the JD incrementing at a different rate for the whole leap-second-containing day. The official formulae that use JD (usually MJD actually) with UTC have it increase always at the standard rate of 1/86400 per second. In that model it undergoes a discontinuity at the end of a leap, decrementing by 1/86400 at the end of a positive leap second. A bit like what the POSIX time_t is specified to do (not what it usually does in practice). See <http://maia.usno.navy.mil/ser7/tai-utc.dat> which uses this model of MJD. The other way to derive a JD from UTC is to use UTC-SLS <http://www.cl.cam.ac.uk/~mgk25/time/utc-sls/>, which changes rate for the last 1000 s of a UTC day. I wrote a module which implements this. -zefram