Reputation: 936
Hi I was able to find the answer to this question but not with the timezone included (http://stackoverflow.com/questions/1712116/formatting-yesterdays-date-in-python)
This is working fine for me:
>>> import time
>>> time.strftime('/%Z/%Y/%m/%d')
'/EST/2013/01/18'
but is there a way to get the yesterdays date? I need to handle the timezone change when we switch from EST to EDT, EDT to EST
datetime modules allows to use timedelta, but the naive object don't support timezones by default and I'm not sure how to handle that.
Upvotes: 1
Views: 3881
Reputation: 2257
For accounting timezone and daylight saving time changes, the datetime.datetime
object needs to be timezone aware, i.e. tzinfo
property should not be None
. This can be done by subclassing the tzinfo
abstract class. The ustimezone
module does exactly that.
>>> import ustimezone
>>> from datetime import datetime, tzinfo, timedelta
>>> yesterday = datetime.now() - timedelta(days=1)
>>> yesterday
datetime.datetime(2013, 1, 17, 18, 24, 22, 106445)
>>> yesterday_aware = yesterday.replace(tzinfo=ustimezone.Eastern)
>>> yesterday.strftime('%Z/%Y/%m/%d')
'EST/2013/01/17' # Will show EDT/EST depending on dst being present or not.
The dst information is captured by the tm_isdst
value of the timetuple.
>>> yesterday_aware.timetuple()
time.struct_time(tm_year=2013, tm_mon=1, tm_mday=17, tm_hour=18, tm_min=24, tm_sec=22, tm_wday=3, tm_yday=17, tm_isdst=0)
>>> _.tm_isdst
>>> 0 # the tm_isdst flag of the time tuple can be used for checking if DST is present or not.
The ustimezone
module here looks something like this (Borrowed from an example in Python datetime reference)
from datetime import datetime, tzinfo, timedelta
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
# A complete implementation of current DST rules for major US time zones.
def first_sunday_on_or_after(dt):
days_to_go = 6 - dt.weekday()
if days_to_go:
dt += timedelta(days_to_go)
return dt
# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# http://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 1)
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
# Sunday in April and to end at 2am (DST time; 1am standard time) on the last
# Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 1)
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
# Sunday in April (the one on or after April 24) and to end at 2am (DST time;
# 1am standard time) on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006
class USTimeZone(tzinfo):
def __init__(self, hours, reprname, stdname, dstname):
self.stdoffset = timedelta(hours=hours)
self.reprname = reprname
self.stdname = stdname
self.dstname = dstname
def __repr__(self):
return self.reprname
def tzname(self, dt):
if self.dst(dt):
return self.dstname
else:
return self.stdname
def utcoffset(self, dt):
return self.stdoffset + self.dst(dt)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
return ZERO
assert dt.tzinfo is self
# Find start and end times for US DST. For years before 1967, return
# ZERO for no DST.
if 2006 < dt.year:
dststart, dstend = DSTSTART_2007, DSTEND_2007
elif 1986 < dt.year < 2007:
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
elif 1966 < dt.year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return ZERO
start = first_sunday_on_or_after(dststart.replace(year=dt.year))
end = first_sunday_on_or_after(dstend.replace(year=dt.year))
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
if start <= dt.replace(tzinfo=None) < end:
return HOUR
else:
return ZERO
Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
Upvotes: 0
Reputation: 2401
the do it yourself method, but i don't know if there is a better method
>>> import time
>>> from datetime import date, timedelta
>>> yesterday = date.today() - timedelta(1)
>>> yesterday = yesterday.strftime('%Y/%m/%d')
>>> yesterday = "/%s/%s" % ( time.tzname[0], yesterday )
>>> print yesterday
'/CET/2013/01/17'
Upvotes: 1