I personally think that the datetime module is one of the standard Python libraries that is not very cool because it has many traps and is difficult to use despite its frequent use.
It's such a datetime module, but when I migrated my Python 2 project to Python 3, I was able to organize the code a lot and was a little impressed, so I will introduce it.
Conversion from unixtime to datetime.datetime
is done with the.fromtimestamp ()
for local time and the.utcfromtimestamp ()
function for UTC.
>>> import time
>>> from datetime import datetime
>>> now = time.time()
>>> now
1415542873.099776
>>> loc = datetime.fromtimestamp(now)
>>> loc
datetime.datetime(2014, 11, 9, 23, 21, 13, 99776)
>>> utc = datetime.utcfromtimestamp(now)
>>> utc
datetime.datetime(2014, 11, 9, 14, 21, 13, 99776)
However, on the contrary, the conversion from datetime
to unixtime cannot be done directly, and it is necessary to convert it to time.struct_time
type once with the .timetuple ()
method.
What's more, when reverting to unixtime from there, you could go with time.mktime ()
for local time, but you needed calendar.timegm ()
for UTC. It's a bit disappointing to import the calendar module just for this.
>>> time.mktime(loc.timetuple())
1415542873.0
>>> import calendar
>>> calendar.timegm(utc.timetuple())
1415542873
The time module only provides an additional timer for each OS to the C language time.h
function, and datetime is designed for Python, so when you try to use it in combination, such a mismatch occurs. Was there.
However, Python 3.3 adds a .timestamp ()
method that creates a unixtime directly on the datetime object.
>>> from datetime import datetime
>>> now = 1415542873.099776
>>> loc = datetime.fromtimestamp(now)
>>> loc.timestamp()
1415542873.099776
However, .timestamp ()
uses tzinfo that datetime itself has, and if datetime (called naive) that does not have tzinfo, it is calculated as local time.
If you want to convert UTC datetime to unixtime, you need to set tz = utc properly. See the next section for this.
timezone
The datetime type of the datetime module that has timezone information is called aware, and the one that does not have timezone information is called naive.
Naive datetime is attractive as a pure type that doesn't get addicted to noisy timezone conversions when interacting with other naive software such as MySQL, but when writing programs that handle both UTC and JST. If you make a mistake and execute +9 twice, it will cause a bug.
IANA publishes a database about the world time zone, but since the timing is not synchronized with the Python version upgrade, the standard library provides only the abstract class, and the actual time zone class that inherits it. Was provided in a non-standard library called pytz.
However, JST and UTC, which do not have daylight saving time so far, are sufficient applications, and it is a little troublesome to use timezone databases all over the world. I feel that I can understand the feelings of ASCII-speaking people who do not want to think about multi-byte environments.
In Python 3, a class called datetime.timezone
that handles timezones with a fixed time difference from UTC and no daylight saving time is provided in the standard library, and for UTC, datetime.timezone.utc
is provided from the beginning. It is provided.
Use this to try the unixtime and datetime conversions we did in the previous section, this time with a aware datetime.
>>> from datetime import datetime, timezone, timedelta
>>> now = 1415542873.099776
>>> JST = timezone(timedelta(hours=+9), 'JST')
>>> loc = datetime.fromtimestamp(now, JST)
>>> utc = datetime.fromtimestamp(now, timezone.utc)
>>> print(loc)
2014-11-09 23:21:13.099776+09:00
>>> print(utc)
2014-11-09 14:21:13.099776+00:00
>>> loc.timestamp()
1415542873.099776
>>> utc.timestamp()
1415542873.099776
You don't even need a calendar module, and you can now write simpler, less buggy code than in Python 2.
To add timezone information to naive datetime, use the .replace ()
method.
>>> naiveutc = datetime.utcfromtimestamp(now)
>>> naiveutc
datetime.datetime(2014, 11, 9, 14, 21, 13, 99776)
>>> naiveutc.replace(tzinfo=timezone.utc).timestamp()
1415542873.099776
Recommended Posts