Problem with dates and daylight savings...

Mark Tolonen nospam at nospam.com
Mon Apr 12 13:31:19 EDT 2004


"John Taylor" <john at spock.fcs.uga.edu> wrote in message
news:c5ebq7$nls$1 at cronkite.cc.uga.edu...
> I was wondering if some one could explain this anomaly.  I wrote a program
to add/subtract
> dates.  For example,
>
> ./ComputeDay.py 2004/04/12 -7 %Y/%m/%d
> 2004/04/05
>
> Here is the anomaly....
> ./ComputeDay.py 2004/04/12 -8 %Y/%m/%d
> 2004/04/03
>
> I would have thought this would have returned the 4th.  I have a feeling
that daylight savings
> has something to do with this, as the time changed on the 3rd.
> Can someone explain this?  How can I correct this problem?
>
> ./ComputeDay.py 2004/04/12 -9 %Y/%m/%d
> 2004/04/02
>
>
>
> Thanks,
> -John
>
>
> Here is the code:
>
> #!/usr/bin/env python2
>
> ##
> ## ComputeDay.py
> ## John Taylor, Apr 12, 2004
> ##
>
> import time
> import sys
>
>
############################################################################
>
> def Usage():
> print
> print "Usage: %s [ t1 ] [ n ] [ format string ]" % sys.argv[0]
> print "Given arguments t1 and n, where n is a positvie or negative
number,"
> print "return the date +/- t1"
> print """format should be a date format string, such as: %Y/%m/%d"""
> print "See the man page for strptime for formatting options"
> print
> print "Example:", sys.argv[0], "2004/03/01 -1 %Y/%m/%d"
> print
> sys.exit()
>
>
>
############################################################################
>
> def main():
> if len(sys.argv) != 4:
> Usage()
>
> fmt = sys.argv[3]
>
> try:
> t1 = time.strptime(sys.argv[1], fmt)
> except ValueError, e:
> print "Error for t1: ", e
> return
>
> try:
> n = int(sys.argv[2])
> except ValueError, e:
> print "Error for n: ", e
> return
>
> oneday = 60 * 60 * 24 * 1.0
> diff = time.mktime(t1) + (n * oneday)
> diff = time.localtime(diff)

When crossing a daylight savings boundary an hour is added or subtracted.
If you display diff at this point, you can see the error:

>>> diff
(2004, 4, 3, 23, 0, 0, 5, 94, 0)

It is 2004/4/3 11:00pm instead of 2004/4/4 12:00am.

One thing the time.mktime() will do is normalize an invalid date/time
specification.  In C it will correct the structure passed to it, but in
Python you have to call time.localtime() to see the correction.  If you
subtract the number of days directly from the date field the time will be
corrected for you.  Example:

>>> t1 = list(time.strptime("2004/4/12","%Y/%m/%d"))
>>> t1
[2004, 4, 12, 0, 0, 0, 0, 103, -1]        # 2004/4/12, 103rd day of year,
DST unknown
>>> t1[2] -= 8
>>> t1
[2004, 4, 4, 0, 0, 0, 0, 103, -1]         # 2004/4/4, invalid weekday and
yearday, DST unknown
>>> time.localtime(time.mktime(t1))  # mktime normalizes values
(2004, 4, 4, 0, 0, 0, 6, 95, 0)            # 95th day of year, standard time

>>> t1[2] -= 8      # another 8 days earlier
>>> t1
[2004, 4, -4, 0, 0, 0, 0, 103, -1]        # date, weekday, yearday invalid.
DST unknown
>>> time.localtime(time.mktime(t1))   # normalize
(2004, 3, 27, 0, 0, 0, 5, 87, 0)          # 2004/3/27, 87th day of year,
standard time.

Mark

>
> try:
> result = time.strftime(fmt, diff)
> except ValueError, e:
> print "Error for result: ", e
> return
>
> print "%s" % ( result )
>
>
############################################################################
>
> main()
>
>
> -- end of code
>





More information about the Python-list mailing list