If you work primarily with UTC datetimes you might find this utcdatetime
makes your life a little bit easier.
>>> import utcdatetime
>>> my_utcdatetime = utcdatetime.utcdatetime(2011, 6, 1, 16, 45)
standard library equivalent:
>>> import datetime
>>> import pytz
>>> my_datetime = datetime.datetime(2011, 6, 1, 16, 45, tzinfo=pytz.UTC)
>>> str(my_utcdatetime)
'2011-06-01T16:45:00Z'
standard library equivalent:
>>> my_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')
'2011-06-01T16:45:00Z'
>>> import utcdatetime
>>> utcdatetime.utcdatetime.from_string('2011-06-01T16:45:00Z')
utcdatetime.utcdatetime(2011, 6, 1, 16, 45)
>>> utcdatetime.utcdatetime.from_string('2011-06-01T16:45:00+00:00')
utcdatetime.utcdatetime(2011, 6, 1, 16, 45)
>>> utcdatetime.utcdatetime.from_string('2011-06-01T18:45:00+02:00')
utcdatetime.utcdatetime(2011, 6, 1, 16, 45)
Note that non-UTC timezones are automatically converted to UTC.
Doing this in the standard library is really nasty for a few reasons:
Suppose you use datetime.datetime.strptime(my_string, '%Y-%m-%dT%H:%M:%S%z')
- The
%z
argument to strptime only accepts±HHMM
, not±HH:MM
or±HH
- The
%z
argument also doesn't know aboutZ
. - The datetime you get back then needs to be converted using
.astimezone(UTC)
- ... but you don't have a
UTC
class so you'll need to usepytz
! - And what about microseconds?
So you'll have to work out the format first, then run a different strptime accordingly.
>>> import utcdatetime
>>> utc_now = utcdatetime.utcdatetime.now()
>>> utc_now
utcdatetime.utcdatetime(2011, 1, 5, 18, 45, 36)
>>> str(utc_now)
`2011-01-05T18:45:36Z'
Not a problem, as long as it's got a timezone:
>>> import datetime
>>> import utcdatetime
>>> europe = pytz.timezone('Europe/London')
>>> my_datetime = europe.localize(datetime.datetime(2010, 6, 10, 18, 45))
>>> utcdatetime.utcdatetime.from_datetime(my_datetime)
utcdatetime.utcdatetime(2010, 6, 10, 17, 45) # Note British Summer Time -> UTC
>>> import utcdatetime
>>> import pytz
>>> my_datetime = utcdatetime.utcdatetime(2010, 6, 10, 17, 45) # Note British summer time
>>> my_datetime.astimezone(pytz.timezone('Europe/London'))
datetime.datetime(2010, 6, 10, 18, 45, tzinfo=<DstTzInfo 'Europe/London' GMT0:00:00 STD>)
I used to work all day with UTC datetimes in Python and I found some baffling things:
- Why do I need to import
pytz
just to get aUTC
timezone class? - Why does
datetime.utcnow()
return a native datetime with no UTC timezone?! - Why does
datetime.isoformat()
use the+00:00
format rather thanZ
for a UTC datetime? - Why do I have to keep writing
%Y-%m-%dT%H:%M:%SZ
every time I parse or format a UTC datetime? - Why do I have to handle all these timezone syntaxes:
Z
,±HH:MM
,±HHMM
,±HH
?!
This (opinionated) library gives you a UTC datetime with a sensible formatter and a parser which handles sane ISO 8601 datetimes.