Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is time.mktime timezone free in python?

I am trying to understand the nature of epoch, and its behavior. Below I tried the same date with 2 different timezone specific datetime with 1 naive datetime

import time
import pytz
from datetime import datetime, timedelta

pst = pytz.timezone('America/Los_Angeles')
t = datetime(year=2015, month=2, day=2)
t = pst.localize(t)
time.mktime(t.timetuple()) 
# outputs 1422864000.0


utc = pytz.utc
k = datetime(year=2015, month=2, day=2)
k = utc.localize(k)
time.mktime(k.timetuple())
# outputs 1422864000.0




o = datetime(year=2015, month=2, day=2)
time.mktime(o.timetuple())
# outputs 1422864000.0

They all have the same epoch, but this is surprising, since the same date in pst should be offset by 7 hours in reference to utc. Can someone explain this?

Thanks

like image 745
Kevin Avatar asked Jun 30 '15 20:06

Kevin


1 Answers

time.mktime() returns the same result because it receives almost (~isdst) the same input in all three cases:

time.struct_time(tm_year=2015, tm_mon=2, tm_mday=2, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=33, ..)

.timetuple() does not store utc offset. It is equivalent to the naive datetime object.

In general, "epoch" i.e., "seconds since epoch" does not depend on timezone. It is neither local time nor utc. Knowing the timestamp you can get both using datetime.fromtimestamp and datetime.utcfromtimestamp correspondingly.

If your local timezone is different from 'America/Los_Angeles' (different utc offset) then all three time instances are different and therefore all three POSIX timestamps are different:

#!/usr/bin/env python3
from datetime import datetime
import pytz # $ pip install pytz

pacific = pytz.timezone('America/Los_Angeles')
naive  = datetime(2015, 2, 2)
pacific_dt = pacific.localize(naive, is_dst=None)
print(pacific_dt.timestamp())

utc_dt = naive.replace(tzinfo=pytz.utc)
print(utc_dt.timestamp())

print(naive.timestamp()) #NOTE: interpret as local time

The last call may use mktime(naive.timetuple()) internally.

Output

1422864000.0
1422835200.0
1422831600.0

Note: all three timestamps are different.

To get POSIX timestamp on older Python versions, see this answer.

like image 87
jfs Avatar answered Oct 21 '22 22:10

jfs