In the code below, I am calculating now epoch and beginning of current day epoch.
import time
import pytz
from datetime import datetime
tz1 = pytz.timezone('CST6CDT')
utc = pytz.timezone('UTC')
now = pytz.UTC.localize(datetime.utcnow())
now_tz = now.astimezone(tz1)
print now_tz
print now_tz.strftime('%s')
begin_day = now_tz.replace(hour=0, minute=0, second=0)
print begin_day
print begin_day.strftime('%s')
print statements:
2012-08-28 13:52:21.595718-05:00 1346187141 2012-08-28 00:00:00.595718-05:00 1346137200
Converting epochs to timestamp with CDT timezone:
1346187141 – Aug 28 2012 15:52:21,
1346137200 – Aug 28 2012 02:00:00
I’d like the second epoch to be beginning of the day but it’s 2 am. It looks like it is still using local timezone PST when converting to epoch.
What am I doing wrong ? or can this be done a different way?
Thanks!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
To convert a datetime with timezone to epoch (POSIX timestamp):
from datetime import datetime
import pytz
tz = pytz.timezone('CST6CDT')
# a datetime with timezone
dt_with_tz = tz.localize(datetime(2012, 8, 28, 19, 33, 50), is_dst=None)
# get timestamp
ts = (dt_with_tz - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1346200430.0
It is how datetime.timestamp method is implemented for timezone-aware datetime objects in Python 3.
To get “now epoch”:
from datetime import datetime now_epoch = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
Or (assuming time uses POSIX epoch):
import time now_epoch = time.time()
Getting “beginning of current day epoch” is more complex because current day may be different in different timezones:
from datetime import datetime, time
import pytz
tz = pytz.timezone('CST6CDT')
# get current date in given timezone
today = datetime.now(tz).date()
# -> datetime.date(2013, 6, 22)
# get beginning of current day in given timezone as a datetime with timezone
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
# -> datetime.datetime(2013, 6, 22, 0, 0, tzinfo=<DstTzInfo 'CST6CDT'...>)
# get timestamp
ts = (midnight - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1371877200.0
See How do I get the UTC time of “midnight” for a given timezone?.
To get “beginning of current day epoch” assuming UTC date:
from datetime import datetime, date # get current date in UTC utc_date = datetime.utcnow().date() # -> datetime.date(2013, 6, 23) # get timestamp ts = (utc_date - date(1970, 1, 1)).days * 86400 # -> 1371945600
See Converting datetime.date/datetime.datetime to UTC timestamp in Python.
Method 2
NOTE: My answer is flat-out wrong. (I’d like to delete it, but am unable to do so until the accept flag is removed.)
Please see J.F.Sebastian’s answer.
Here is code demonstrating a value of now_tz for which our two methods produce different results.
import calendar
import pytz
import datetime as dt
tz1 = pytz.timezone('US/Eastern')
utc = pytz.timezone('UTC')
now = utc.localize(dt.datetime(2002, 10, 28), is_dst=None)
now_tz = now.astimezone(tz1)
now_epoch = calendar.timegm(now_tz.utctimetuple())
begin_day = tz1.normalize(now_tz.replace(hour=0, minute=0, second=0))
midnight = tz1.localize(dt.datetime.combine(now_tz, dt.time(0, 0)), is_dst=None)
if begin_day != midnight:
print(begin_day)
# 2002-10-27 01:00:00-04:00 # my result -- is not midnight
print(midnight)
# 2002-10-27 00:00:00-04:00 # J.F.Sebastian's result is correct
(Original answer redacted)
Method 3
the latest release of simple-date (version 0.2 on pypi) will manage the details for you:
>>> from simpledate import * >>> now_utc = SimpleDate(tz='UTC') >>> now_tz = now_utc.convert(tz='CST6CDT') >>> begin_day = now_tz.replace(hour=0, minute=0, second=0, microsecond=0) >>> now_utc.timestamp 1371950295.777453 >>> now_tz.timestamp 1371950295.777453 >>> begin_day.timestamp 1371877200.0
we can go backwards to check the timestamps (although it’s clear above that switching timezone didn’t change the epoch, while moving to start of day did):
>>> SimpleDate(1371877200.0, tz='CST6CDT')
SimpleDate('2013-06-22 00:00:00.000000 CDT', tz='CST6CDT')
>>> SimpleDate(1371877200.0, tz='UTC')
SimpleDate('2013-06-22 05:00:00.000000 UTC')
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0