datetimes, tzinfo and gmtime epoch

John Hunter jdhunter at ace.bsd.uchicago.edu
Mon Apr 19 10:47:47 EDT 2004


>>>>> "John" == John Hunter <jdhunter at ace.bsd.uchicago.edu> writes:

    John> No goddawgy, I'm still off by an hour.  Basically, I need to
    John> go from datetime -> gm epoch time -> and back while properly
    John> accounting for dst.

Ok, for future generations of google-groupers looking for a free ride,
I think I finally got this one figured out.  The problem arose from
the fact that I wanted to be able to support dates in any timezone but
obviously the mktime offset needs to be in localtime.  In my example,
the tz was Eastern but my localtime is Central which accounts for the
1 hour discrepancy.  The key is to use the arbitrary tzinfo in the
datetime constructor but the Local tzinfo instance in computing the
mktime offset.  Obvious once you realize it.

Thanks Tim Peters for defining all these nice tzinfo classes!  Why
aren't these part of the standard datetime module, or are they lurking
somewhere in there?

from your_timezone_module import Eastern, Pacific, Central, Local
import time
from datetime import datetime

SEC_PER_DAY = 24*3600
class PyDatetimeConverter:
    """
    Convert python2.3 datetime instances to/from epoch gmtime
    """

    def __init__(self, tz=Eastern):
        self.tz = tz
        self.local = Local
        
    def epoch(self, x):
        'convert userland datetime instance x to epoch'        
        offset = self.local.utcoffset(x).days*SEC_PER_DAY + \
                 self.local.utcoffset(x).seconds
        return time.mktime( x.timetuple() ) + offset

    def from_epoch(self, e):
        'return a datetime  from the epoch'
        y,month,d,h,m,s,wd,jd,ds = time.gmtime(e)
        return datetime(y,month,d,h,m,s, tzinfo=self.tz)

tz = Pacific
dt1 = datetime(2004, 03, 01, tzinfo=tz)  # before dst
dt2 = datetime(2004, 04, 15, tzinfo=tz)  # after dst

dtc = PyDatetimeConverter(tz)

assert( dtc.from_epoch( dtc.epoch(dt1) ) == dt1 )
assert( dtc.from_epoch( dtc.epoch(dt2) ) == dt2 )





More information about the Python-list mailing list