 <p>For accounting timezone and daylight saving time changes, the <code>datetime.datetime</code> object needs to be timezone aware, i.e. <code>tzinfo</code> property should not be <code>None</code>. This can be done by subclassing the <code>tzinfo</code> abstract class. The <code>ustimezone</code> module does exactly that.</p> <pre><code>&gt;&gt;&gt; import ustimezone &gt;&gt;&gt; from datetime import datetime, tzinfo, timedelta &gt;&gt;&gt; yesterday = datetime.now() - timedelta(days=1) &gt;&gt;&gt; yesterday datetime.datetime(2013, 1, 17, 18, 24, 22, 106445) &gt;&gt;&gt; yesterday_aware = yesterday.replace(tzinfo=ustimezone.Eastern) &gt;&gt;&gt; yesterday.strftime('%Z/%Y/%m/%d') 'EST/2013/01/17' # Will show EDT/EST depending on dst being present or not. </code></pre> <p>The dst information is captured by the <code>tm_isdst</code> value of the timetuple.</p> <pre><code>&gt;&gt;&gt; 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) &gt;&gt;&gt; _.tm_isdst &gt;&gt;&gt; 0 # the tm_isdst flag of the time tuple can be used for checking if DST is present or not. </code></pre> <p>The <code>ustimezone</code> module here looks something like this (Borrowed from an example in Python <a href="http://docs.python.org/dev/library/datetime.html" rel="nofollow">datetime</a> reference)</p> <pre><code>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 &lt; dt.year: dststart, dstend = DSTSTART_2007, DSTEND_2007 elif 1986 &lt; dt.year &lt; 2007: dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006 elif 1966 &lt; dt.year &lt; 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 &lt;= dt.replace(tzinfo=None) &lt; end: return HOUR else: return ZERO Eastern = USTimeZone(-5, "Eastern", "EST", "EDT") </code></pre>