5

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

Kevin
  • 371
  • 3
  • 7
  • 14
  • 1
    have you tried running `help(time.mktime)` ? tl;dr `help(time.mktime)` outputs : `Convert a time tuple in local time to seconds since the Epoch.` which means, no it doesnt care what time zone, it assumes its local. – TehTris Jun 30 '15 at 20:44
  • @TehTris so is the final epoch local time adjusted? or is it always utc? – Kevin Jun 30 '15 at 23:16

1 Answers1

7

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.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670