#!/usr/bin/env python # ----------------------------------------------------------------------- # Copyright (C) 2003 Chris Ottrey. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MER- # CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # ----------------------------------------------------------------------- # # This code is part of the pytvgrab project: # http://pytvgrab.sourceforge.net # # ----------------------------------------------------------------------- # Subversion Information, do not edit # # $Rev: 291 $ # $LastChangedDate: 2004-11-21 23:37:37 +1100 (Sun, 21 Nov 2004) $ # $LastChangedRevision: 291 $ # $LastChangedBy: ottrey $ # # $Log: $ # """ Datetime library This is an extended version of the standard time library. """ import re import time import sys import os import copy import datetime import message from i18n import _ WINDOWS_MKTIME_BUG_FIX=60*60*24 # There's a problem using 1/1/1970 as epoc - so use 2/1/1970 instead. True=1 False=0 #For python version detection python23 = True if sys.version < "2.3": python23 = False sys.stderr.write(_( "WARNING : You're using something older then " \ "Python 2.3\n" ) ) sys.stderr.write(_( "You may experience some problems with Timezone " \ "handling.\n" ) ) # --- Functions --- # def today(output_fmt=None): """Current Date in localtime""" return Date('', output_fmt=output_fmt) # today() def now(output_fmt=None): """Current Time in localtime""" return Time('', output_fmt=output_fmt) # now() def nowdt(output_fmt=None): """Current DateTime in localtime""" result=DateTime('', output_fmt=output_fmt) # adjust for daylight savings time if result.t[8] and not python23: result.addHours(1) return result # nowdt() def tzone(t): """RFC-822 style numeric timezone (-0500)""" if t[8]: x=(0-time.altzone)/60 else: x=(0-time.timezone)/60 return '%+03d%02d' % (x/60, x%60) # tzone() class _DateTime: """Base class""" output_fmt='%Y%m%d%H%M %z' _pattern={} def __init__(self, buf=None, output_fmt=None, input_fmt=None, tzinfo=None): t=None if tzinfo: self.tzInfo = tzinfo if buf: self.buf=buf if input_fmt: t=time.strptime(buf, input_fmt) else: for p in self._pattern.keys(): if p.match(buf): t=self._getTime(p) if not t: msg=_( "Couldn't match buffer %s with any of the known formats." ) \ % repr(buf) exception=Exception(msg) exception.__class__.__name__='%s%s' % (self.__class__.__name__, 'Exception') raise exception else: t=time.localtime() self._setTime(t) if output_fmt: self.output_fmt=output_fmt # __init__() def copy(self): """Return a copy of the object""" return copy.copy(self) # copy() def range(self, n1, n2=None, step=1): """Return a set of objects""" result=[] if n2 != None: for i in range(n1, n2, step): result.append(self+i) else: for i in range(n1): result.append(self+i) return result # range() def strftime(self, output_fmt=None): """Return strftime()""" result='' fmt=self.output_fmt if output_fmt: fmt=output_fmt if self.t: result=time.strftime(fmt, self.t) return result # strftime() def _getTime(self, p): self.input_fmt=self._pattern[p] result=None try: result=time.strptime(self.buf, self.input_fmt) except: raise Exception('ERROR %s: Bad fmt %s for string %s\n' % (__file__, self.input_fmt, self.buf)) return result # _getTime() def _setTime(self, t): pass def _subObject(self, ob): """Return difference between objects in n*_step seconds""" t1=time.mktime(self.t) t2=time.mktime(ob.t) t=t1-t2 result=t/self._step return result # _subObject() def __add__(self, n): """Return new object plus n*_step seconds""" result=self.copy() secs1=time.mktime(self.t) secs2=secs1+(n*self._step) result.t=time.localtime(secs2) return result # __add__() def __sub__(self, right): """Return new object minus n*_step seconds""" if type(right) == type(1): n=right return self.__add__(0-n) elif type(right) == type(self): ob=right return self._subObject(ob) # __sub__() def __cmp__(self, ob): """Return comparison between objects""" t1=time.mktime(self.t) t2=time.mktime(ob.t) return cmp(t1, t2) # __cmp__() def __hash__(self): """Return a hash using ctime""" return int(time.mktime(self.t)) # __hash__() def __call__(self, output_fmt=None): """Return strftime()""" return self.strftime(output_fmt) # __call__() def __repr__(self): return repr(str(self)) # __repr__() def __str__(self): # tzone doesn't work for me. :-/ #return self.strftime(self.output_fmt) output_fmt=self.output_fmt.replace('%z', self._tzone()) return self.strftime(output_fmt) # __str__() def _tzone(self): if hasattr(self,'tzinfo'): t = self.t x = self.tzinfo.utcoffset( datetime.datetime(t[0],t[1],t[2],t[3],t[4],t[5])) x = x.seconds/60 + x.days*60*24 return '%+03d%02d' % (x/60, x%60) else: return tzone(self.t) # _DateTime class Time(_DateTime): """Time Some example usages: >>> t=now() >>> t1=now('%H:%M:%S') >>> t2=now('%H.%M %p') >>> print t, t1, t2 1235 12:36:16 12.36 PM >>> t3=Time('3.43pm') >>> t, t1, t2, t3 ('1235', '12:36:16', '12.36 PM', '1543') >>> t4=Time('1PM') >>> Time.output_fmt='%H:%M:%S' >>> t, t1, t2, t3, t4 ('12:35:56', '12:36:16', '12.36 PM', '15:43:00', '13:00:00') >>> times=t, t1, t2, t3, t4 >>> lunchtime=Time('13:00') >>> for time in times: ... if time < lunchtime: ... print '%s is before lunchtime' % time(lunchtime.input_fmt) ... elif time > lunchtime: ... print '%s is after lunchtime' % time(lunchtime.input_fmt) ... elif time == lunchtime: ... print '%s is at lunchtime' % time(lunchtime.input_fmt) ... else: ... raise Exception('error') ... 12.35 is before lunchtime 12.36 is before lunchtime 12.36 is before lunchtime 15.43 is after lunchtime 13.00 is at lunchtime """ output_fmt='%H%M' _step=1 _pattern={ re.compile(r'^[1-2]?[0-9](a|p)m$') : '%I%p', re.compile(r'^[1-2]?[0-9](A|P)M$') : '%I%p', re.compile(r'^[1-2]?[0-9]([.][0-5][0-9])(a|p)m$') : '%I.%M%p', re.compile(r'^[1-2]?[0-9]([.][0-5][0-9])(A|P)M$') : '%I.%M%p', re.compile(r'^[1-2]?[0-9]([.][0-5][0-9]) (a|p)m$') : '%I.%M %p', re.compile(r'^[1-2]?[0-9]([.][0-5][0-9]) (A|P)M$') : '%I.%M %p', re.compile(r'^[0-2][0-9]:[0-5][0-9]$') : '%H:%M', re.compile(r'^[0-2][0-9][.][0-5][0-9]$') : '%H.%M', re.compile(r'^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$') : '%H:%M:%S', } def addSeconds(self, n): """Add n seconds to self""" secs1=time.mktime(self.t) secs2=secs1+n t=time.localtime(secs2) self._setTime(t) return self # addSecond() def subSeconds(self, n): """Subtract n seconds from self""" return self.addSeconds(0-n) # subSecond() def nextSecond(self): """Add 1 second to self""" return self.addSeconds(1) # nextSecond() def addMinutes(self, n): """Add n minutes to self""" return self.addSeconds(n*60) # addMinute() def subMinutes(self, n): """Subtract n minutes from self""" return self.addSeconds(0-n*60) # subMinute() def nextMinute(self): """Add 1 minute to self""" return self.addSeconds(60) # nextMinute() def addHours(self, n): """Add n hours to self""" return self.addSeconds(n*3600) # addHour() def subHours(self, n): """Subtract n hours from self""" return self.addSeconds(0-n*3600) # subHour() def nextHour(self): """Add 1 hour to self""" return self.addSeconds(3600) # nextHour() def _setTime(self, t): """Set the time, using UTC and date 1/1/1970 all Time objects.""" t0=list(time.gmtime(WINDOWS_MKTIME_BUG_FIX)) t1=list(t) t1[:3]=t0[:3] t1[6:]=t0[6:] self.t=tuple(t1) # _setTime() def __add__(self, right): if type(right) == type(1): n=right return _DateTime.__add__(self, n) elif type(right) == type(Date()): ob=right return ob._addTime(self) # __add__() # Time class Date(_DateTime): """Date Some example usages: >>> today('%A, %d %B, %Y') 'Saturday, 06 September, 2003' >>> for day in today('%A, %d %B, %Y').range(4): print day ... Saturday, 06 September, 2003 Sunday, 07 September, 2003 Monday, 08 September, 2003 Tuesday, 09 September, 2003 >>> xmas=Date('25/12/2003') >>> xmas '20031225' >>> xmas=Date('25/12/2003', output_fmt='%a, %b %d, %Y') >>> xmas 'Thu, Dec 25, 2003' >>> xmas=Date('25/12/2003', output_fmt='%a %b %d %Y') >>> xmas 'Thu Dec 25 2003' >>> boxing_day=xmas+1 >>> boxing_day 'Fri Dec 26 2003' >>> new_years_day=Date('1/1/2004') >>> print new_years_day 20040101 >>> print new_years_day - xmas 7.0 >>> print 'New Years day in on %s' % (xmas+7) New Years day in on Thu Jan 01 2004 """ output_fmt='%Y%m%d' _step=60*60*24 _pattern={ re.compile(r'[A-Z][a-z]{2}[a-z]+, [0-9]{1,2} [A-Z][a-z]+, [0-9]{4}$', re.IGNORECASE) : '%A, %d %B, %Y', re.compile(r'[A-Z][a-z]{2}[a-z]+, [0-9]{1,2} [A-Z][a-z]+ [0-9]{4}$', re.IGNORECASE) : '%A, %d %B %Y', re.compile(r'[A-Z][a-z]{2}, [0-9]{1,2} [A-Z][a-z]+, [0-9]{4}$', re.IGNORECASE) : '%a, %d %B, %Y', re.compile(r'[A-Z][a-z]{2}, [0-9]{1,2} [A-Z][a-z]+ [0-9]{4}$', re.IGNORECASE) : '%a, %d %B %Y', re.compile(r'[0-9]{4}[0-9]{2}[0-9]{2}$', re.IGNORECASE) : '%Y%m%d', re.compile(r'[0-9]{2}/[0-9]{2}/[0-9]{4}$', re.IGNORECASE) : '%d/%m/%Y', re.compile(r'[0-9]{4}-[0-9]{2}-[0-9]{2}$', re.IGNORECASE) : '%Y-%m-%d', # Dedicated to Dan's old teacher. ;-) re.compile(r'(?P([1-3])?[0-9])/(?P(1)?[0-9])/(?P[0-9]{4})$', re.IGNORECASE) : 'unsupported_input_fmt_1', } def addDays(self, n): """Add n days to self""" secs1=time.mktime(self.t) secs2=secs1+(n*60*60*24) t=time.localtime(secs2) self._setTime(t) return self # addDays() def subDays(self, n): """Subtract n days from self""" return self.addDays(0-n) # subDays() def nextDay(self): """Add 1 day to self""" return self.addDays(1) # nextDay() def _getTime(self, p): """Get the time from formats that aren't supported in the time library.""" result=None buf=self.buf input_fmt=self._pattern[p] if input_fmt == 'unsupported_input_fmt_1': d=p.match(buf).groupdict() buf='%02d/%02d/%d' % (int(d['day']), int(d['month']), int(d['year'])) input_fmt='%d/%m/%Y' self.input_fmt=input_fmt result=time.strptime(buf, self.input_fmt) return result # _getTime() def _setTime(self, t): """Set the time, using UTC and date 1/1/1970 all Time objects.""" t0=list(time.localtime(0)) t1=list(t) t1[3:6]=t0[3:6] self.t=tuple(t1) # _setTime() def _addTime(self, ob): return DateTime(self, ob) # _addTime() def __add__(self, right): if type(right) == type(1): n=right return _DateTime.__add__(self, n) elif type(right) == type(Time()): ob=right return self._addTime(ob) # __add__() # Date class DateTime(Date, Time): """DateTime Some example usages: >>> d=today() >>> t=now() >>> dt1=d+t >>> dt2=nowdt() >>> d, t, dt1, dt2 ('20030906', '1302', '13:02:12 Saturday, 06 September, 2003', '13:02:23 Saturday, 06 September, 2003') >>> DateTime.output_fmt='%c' >>> d, t, dt1, dt2 ('20030906', '1302', 'Sat Sep 6 13:02:12 2003', 'Sat Sep 6 13:02:23 2003') >>> dt2-dt1 11.0 >>> dt1('%d/%m/%Y %H:%M:%S') '06/09/2003 13:02:12' """ _step=Time._step output_fmt='%H:%M:%S %A, %d %B, %Y' def __init__(self, mydate=None, mytime=None, output_fmt=None, tzinfo=None): if tzinfo: self.tzinfo = tzinfo if not mydate: mydate=today() if not mytime: mytime=now() if output_fmt: self.output_fmt=output_fmt secs1=time.mktime(mydate.t) secs2=time.mktime(mytime.t) secs=secs1+secs2-WINDOWS_MKTIME_BUG_FIX if False: # os.name != 'posix': # ie. your system (Windows?) has another bug in the time library! secs+=1 self.t=time.localtime(secs) # adjust for east of UTC if time.altzone > 0: self.subDays(1) # un-adjust for daylight savings time if self.t[8] and not python23: self.subHours(1) # __init__() def _setTime(self, t): self.t=t # _setTime() # DateTime # -------------- Unit Tests -------------- # using_unittest2=False try: import unittest2 as unittest using_unittest2=True except: import unittest class Time_UnitTest(unittest.TestCase): def test01(self): v=str(Time('1.23am')); assert v == '0123', v def test02(self): v=str(Time('1.24pm')); assert v == '1324', v def test03(self): v=str(Time('1.25AM')); assert v == '0125', v def test04(self): v=str(Time('1.26PM')); assert v == '1326', v def test05(self): v=str(Time('01:29' )); assert v == '0129', v def test06(self): v=str(Time('13:30' )); assert v == '1330', v def test07(self): v=str(Time('13.31' )); assert v == '1331', v def test08(self): v=str(Time('13.32', '%H:%M' )) ; assert v == '13:32', v def test09(self): v=str(Time('13:34:00').addSeconds(3*60)); assert v == '1337', v def test10(self): v=str(Time('13:38:00').subSeconds(3*60)); assert v == '1335', v def test11(self): v=str(Time('13:38:00', output_fmt='%H:%M:%S').nextSecond()); assert v == '13:38:01', v def test12(self): v=str(Time('13:34:00').addMinutes(3)) ; assert v == '1337', v def test13(self): v=str(Time('13:38:00').subMinutes(3)) ; assert v == '1335', v def test14(self): v=str(Time('13:38:00').nextMinute()) ; assert v == '1339', v def test15(self): v=str(Time('13:34:00').addHours(3)) ; assert v == '1634', v def test16(self): v=str(Time('13:38:00').subHours(3)) ; assert v == '1038', v def test17(self): v=str(Time('13:38:00').nextHour()) ; assert v == '1438', v def test18(self): v=str(Time('13:34:00') + 3*60) ; assert v == '1337', v def test19(self): v=str(Time('13:38:00') - 3*60) ; assert v == '1335', v def test20(self): v=(Time('1.39pm') - Time('11.57am')); assert v == 60*102, v def test21(self): v=(Time('1.41pm') < Time('13:52') ); assert v == True, v def test22(self): v=(Time('1.41pm') > Time('1.53am') ); assert v == True, v def test23(self): v=(Time('1.41pm') == Time('13.41') ); assert v == True, v def test24(self): v=(Time('12.00am') < Time('00:01') ); assert v == True, v def test25(self): v=(Time('12.01am') < Time('00:02') ); assert v == True, v def test26(self): v=(Time('12.58am') < Time('00:59') ); assert v == True, v def test27(self): v=(Time('12.59am') < Time('01:00') ); assert v == True, v def test28(self): v=(Time('1.00am') < Time('01:01') ); assert v == True, v def test29(self): v=(Time('1.01am') < Time('01:02') ); assert v == True, v def test30(self): v=(Time('10.59pm') < Time('23:00') ); assert v == True, v def test31(self): v=(Time('11.00pm') < Time('23:01') ); assert v == True, v def test32(self): v=(Time('11.01pm') < Time('23:02') ); assert v == True, v def test33(self): v=(Time('11.58pm') < Time('23:59') ); assert v == True, v def test34(self): v=(Time('11.59pm') < Time('00:00') ); assert v == False, v def test35(self): v=str(Time('22:59:58', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '22:59:59', v def test36(self): v=str(Time('22:59:59', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '23:00:00', v def test37(self): v=str(Time('23:00:00', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '23:00:01', v def test38(self): v=str(Time('23:59:58', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '23:59:59', v def test39(self): v=str(Time('23:59:59', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '00:00:00', v def test40(self): v=str(Time('00:00:00', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '00:00:01', v def test41(self): v=str(Time('00:00:01', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '00:00:02', v def test42(self): v=str(Time('00:59:58', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '00:59:59', v def test43(self): v=str(Time('00:59:59', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '01:00:00', v def test44(self): v=str(Time('01:00:00', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '01:00:01', v def test45(self): v=str(Time('01:00:01', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '01:00:02', v def test46(self): v=str(Time('01:59:58', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '01:59:59', v def test47(self): v=str(Time('01:59:59', output_fmt='%H:%M:%S').addSeconds(1)); assert v == '02:00:00', v class Date_UnitTest(unittest.TestCase): def test01(self): v=str(Date('Friday, 18 July, 2003')); assert v == '20030718', v def test02(self): v=str(Date('Friday, 4 July, 2003' )); assert v == '20030704', v def test03(self): v=str(Date('Friday, 04 July, 2003')); assert v == '20030704', v def test04(self): v=str(Date('Friday, 25 July, 2003')); assert v == '20030725', v def test05(self): v=str(Date('Fri, 25 July, 2003' )); assert v == '20030725', v def test06(self): v=str(Date('20030726' )); assert v == '20030726', v def test07(self): v=str(Date('20030809' )); assert v == '20030809', v def test08(self): v=str(Date('2/9/2003' )); assert v == '20030902', v def test09(self): v=str(Date('20030726').subDays(1) ); assert v == '20030725', v def test10(self): v=str(Date('20030726').addDays(1) ); assert v == '20030727', v def test11(self): v=str(Date('20030726').subDays(27) ); assert v == '20030629', v def test12(self): v=str(Date('20040101').subDays(2) ); assert v == '20031230', v def test13(self): v=str(Date('20031230').addDays(3) ); assert v == '20040102', v def test14(self): v=str(Date('01/09/2003', '%A, %d %B, %Y' )) \ ; assert v == 'Monday, 01 September, 2003', v def test15(self): v=str(Date('09/01/2003', output_fmt='%A, %d %B, %Y', input_fmt='%m/%d/%Y' )); assert v == 'Monday, 01 September, 2003', v def test16(self): v=str(Date('20031230') + 3); assert v == '20040102', v def test17(self): v=str(Date('20040101') - 2); assert v == '20031230', v def test18(self): v=(Date('20040101') - Date('20031230') ); assert v == 2, v def test19(self): v=(Date('20040101') > Date('30/12/2003')); assert v == True, v def test20(self): v=(Date('20020101') < Date('30/12/2003')); assert v == True, v def test21(self): v=(Date('20030902') == Date('Tuesday, 02 September, 2003')); assert v == True, v def test22(self): v=str(Date('2004-10-28')); assert v == '20041028', v class DateTime_UnitTest(unittest.TestCase): def test01(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) ) ; assert v == '13:23:00 Monday, 01 September, 2003', v def test02(self): v=str(Date('01/09/2003') + Time('1.23pm')) ; assert v == '13:23:00 Monday, 01 September, 2003', v def test03(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).addSeconds(2) ) ; assert v == '13:23:02 Monday, 01 September, 2003', v def test04(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).subDays(2) ) ; assert v == '13:23:00 Saturday, 30 August, 2003', v def test05(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) + 45 ) ; assert v == '13:23:45 Monday, 01 September, 2003', v def test06(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).nextDay().nextDay().nextDay().nextDay() ); assert v == '13:23:00 Friday, 05 September, 2003', v def test07(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) +40+2+2+1 ); assert v == '13:23:45 Monday, 01 September, 2003', v def test08(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) ); assert v == '13:23:00 Monday, 01 September, 2003', v def test09(self): v=str(Date('01/09/2003') + Time('1.23pm')); assert v == '13:23:00 Monday, 01 September, 2003', v def test10(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).addSeconds(2) ); assert v == '13:23:02 Monday, 01 September, 2003', v def test11(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).subDays(2) ); assert v == '13:23:00 Saturday, 30 August, 2003', v def test12(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) + 45 ); assert v == '13:23:45 Monday, 01 September, 2003', v def test13(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')).nextDay().nextDay().nextDay().nextDay() ); assert v == '13:23:00 Friday, 05 September, 2003', v def test14(self): v=str(DateTime(Date('01/09/2003'), Time('1.23pm')) +40+2+2+1 ); assert v == '13:23:45 Monday, 01 September, 2003', v def test15(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) ) ; assert v == '13:23:00 Saturday, 01 March, 2003', v def test16(self): v=str(Date('01/03/2003') + Time('1.23pm')) ; assert v == '13:23:00 Saturday, 01 March, 2003', v def test17(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).addSeconds(2) ) ; assert v == '13:23:02 Saturday, 01 March, 2003', v def test18(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).subDays(2) ) ; assert v == '13:23:00 Thursday, 27 February, 2003', v def test19(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) + 45 ) ; assert v == '13:23:45 Saturday, 01 March, 2003', v def test20(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).nextDay().nextDay().nextDay().nextDay() ) ; assert v == '13:23:00 Wednesday, 05 March, 2003', v def test21(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) +40+2+2+1 ) ; assert v == '13:23:45 Saturday, 01 March, 2003', v def test22(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) ) ; assert v == '13:23:00 Saturday, 01 March, 2003', v def test23(self): v=str(Date('01/03/2003') + Time('1.23pm')) ; assert v == '13:23:00 Saturday, 01 March, 2003', v def test24(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).addSeconds(2) ) ; assert v == '13:23:02 Saturday, 01 March, 2003', v def test25(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).subDays(2) ) ; assert v == '13:23:00 Thursday, 27 February, 2003', v def test26(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) + 45 ) ; assert v == '13:23:45 Saturday, 01 March, 2003', v def test27(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')).nextDay().nextDay().nextDay().nextDay() ) ; assert v == '13:23:00 Wednesday, 05 March, 2003', v def test28(self): v=str(DateTime(Date('01/03/2003'), Time('1.23pm')) +40+2+2+1 ) ; assert v == '13:23:45 Saturday, 01 March, 2003', v def test29(self): # NB. This test is not guaranteed to pass every ~time~! v=str(nowdt('%a, %d %b %Y %H:%M')); assert v == time.strftime('%a, %d %b %Y %H:%M', time.localtime()), v def test30(self): #This should detect tz/dst bugs creeping in when adding dates with a time when using today and now ftions v=str((Date()) + (Time('06:00')) )[0:8] ; assert v == '06:00:00', v def test31(self): v=str(Time('1.23pm') + Date('01/09/2003')) ; assert v == '13:23:00 Monday, 01 September, 2003', v if using_unittest2 or __name__ == '__main__': unittest.main() # -------------- Unit Tests -------------- #