Skip to content

Instantly share code, notes, and snippets.

@lernisto
Last active July 13, 2019 17:19
Show Gist options
  • Save lernisto/a4c24420429531b362cc8faf3a24f5fb to your computer and use it in GitHub Desktop.
Save lernisto/a4c24420429531b362cc8faf3a24f5fb to your computer and use it in GitHub Desktop.
Various ways to get a current timestamp or convert a timestamp to a `datetime`
#!/usr/bin/env python3
'''
I spent way too much time messing with timestamps.
A timestamp is the number of seconds elapsed since the epoch.
A unix timestamp uses the unix epoch, which is defined as
1970-01-01T00:00:00+00:00
Takeaways
* the `datetime` module handles two different types of datetimes:
1. "naive" times don't know their timezone
2. "aware" times do know their timezone
* most functions treat a naive time as a local time
* `datetime.utcnow()` is evil: it creates a naive time that is not local time
* ditto for `datetime.utcfromtimestamp()`
* use `datetime.now(UTC)` or `datetime.fromtimestamp(t,UTC)` instead
* avoid using naive times
'''
import time
from datetime import datetime as DT
from datetime import timezone
UTC = timezone.utc
EPOCH = DT.fromtimestamp(0,UTC)
TEMPLATE ="{:24} {:10d} {:32} {:32} {:32}"
print("Unix epoch:",EPOCH.isoformat())
print()
def prtime(label,dt,template=TEMPLATE):
ts = round(dt.timestamp())
plain = dt.isoformat()
local = dt.astimezone().isoformat()
utc = dt.astimezone(UTC).isoformat()
print(template.format(label,ts,plain,local,utc))
def mktime(label,func,*args,**kw):
dt = func(*args,**kw)
prtime(label,dt)
return dt
now = time.time()
rnow = round(now)
dates = [ mktime(*args) for args in
(
# naive. wrong unless local time is UTC
("DT.utcfromtimestamp(t)",DT.utcfromtimestamp,now),
# correct, but naive
("DT.fromtimestamp(t)",DT.fromtimestamp,now),
# correct and aware
("DT.fromtimestamp(t,UTC)",DT.fromtimestamp,now,UTC),
# naive. wrong unless local time is UTC
("DT.utcnow()",DT.utcnow),
# correct, but naive
("DT.now()",DT.now),
# correct and aware
("DT.now(UTC)",DT.now,UTC),
)
]
# these should all represent approximately the same time
for d in dates:
print(round(d.timestamp())==rnow)
@lernisto
Copy link
Author

note that utcfromtimestamp() has the same problem as utcnow()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment