How to check if it's xx:00:00 with a timestamp?

1.6k Views Asked by At

It seems that checking if it's xx:00:00 UTC/GMT is as simple as checking if timestamp % 3600 == 0, with timestamp = number of seconds elapsed since epoch (1970-01-01 00:00:00). We can see it here:

import datetime 
print datetime.datetime.fromtimestamp(3600*24*17000)
# 2016-07-18 02:00:00

But isn't this in contradiction with leap seconds? Indeed, the number of seconds elapsed between 1970-01-01 00:00:00 and 2016-07-18 02:00:00 is not a multiple of 3600, but a multiple of 3600 + 26 leap seconds (there have been 26 leap seconds between 1972 and now).


To be more precise: the number of elapsed seconds between 1970-01-01 00:00:00 and 2016-07-18 02:00:00 is 3600*24*17000 + 26 and not 3600*24*17000.

2

There are 2 best solutions below

4
On

Python's datetime.datetime objects can not handle leap seconds since the seconds attribute is limited to the range 0..59:

In [19]: DT.datetime(2012, 6, 30, 23, 59, 60)
ValueError: second must be in 0..59

(There was a leap second just before midnight, 2012-06-30).

So Python's datetime system does not quite represent all times as they exist in the real world. It models a simplified world where no leap seconds exist.

See also: this python issue which was closed with status "won't fix".

The linked page shows mxDatetime as an alternative to datetime.datetime which can (sort of) handle leap seconds.

1
On

I finally found it here:

When a leap second is inserted, which happens about every year and a half on average, the Unix time number increases continuously during the leap second, during which time it is more than 86,400 seconds since the start of the current day, and then jumps back by 1 at the end of the leap second, which is the start of the next day

1998-12-31T23:59:59.75  915 148 799.75
1998-12-31T23:59:60.00  915 148 800.00  # leap second here
1998-12-31T23:59:60.25  915 148 800.25
1998-12-31T23:59:60.50  915 148 800.50
1998-12-31T23:59:60.75  915 148 800.75
1999-01-01T00:00:00.00  915 148 800.00  # timestamp jumps back!
1999-01-01T00:00:00.25  915 148 800.25

So probably there's some code somewhere in datetime.py that does this leap second detection + jumping back. There's a reference to "leap second" here but I can't see how it could detect if it's one or not.

import datetime 
print datetime.datetime.fromtimestamp(915148799) #1999-01-01 00:59:59
print datetime.datetime.fromtimestamp(915148800) #1999-01-01 01:00:00