views:

177

answers:

2

I seem to have a hard time getting my head around this.

What's the difference between calendar.timegm() and time.mktime()?

Say I have a datetime.datetime with no tzinfo attached, shouldn't the two give the same output? Don't they both give the number of seconds between epoch and the date passed as a parameter? And since the date passed has no tzinfo, isn't that number of seconds the same?

>>> import calendar
>>> import time
>>> import datetime
>>> d = datetime.datetime(2010, 10, 10)
>>> calendar.timegm(d.timetuple())
1286668800
>>> time.mktime(d.timetuple())
1286640000.0
>>> 
A: 

calendar.timegm converts from UTC timestamp, time.mktime converts from local time not UTC.

8 hours difference in their results corresponds exactly to timezone of your location.

SilentGhost
More precisely, timegm interprets the given date as UTC, returning a timestamp, while mktime interprets the given date as local time, returning a timestamp.
Greg Hewgill
@Greg: corrected. misread the docs :)
SilentGhost
+2  A: 

time.mktime() assumes that the passed tuple is in local time, calendar.timegm() assumes its in GMT/UTC. Depending on the interpretation the tuple represents a different time, so the functions return different values (seconds since the epoch are UTC based).

The difference between the values should be equal to the time zone offset of your local time zone.

sth
Oh, I see, so basically timegm assumes I passed UTC and simply makes the difference between what I passed and 1970.01.01 UTC, whereas mktime first converts what I passed to UTC by adding my timezone offset and does what timegm did from there on?
ionut bizau
But WHY if my datetime's tzinfo is None does mktime do ANY conversion? Shouldn't it leave it as it is? Why would it assume it's in local time zone?
ionut bizau
@ibz: The `timetuple` parameter given to `mktime()` doesn't contain any time zone information (it never does, there is no time zone field in a `timetuple`). Therefore the function has to "guess" which time zone it might be, and `mktime()` just always assumes that it is local time. That's just how the function behaves.
sth