# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1240928492 -7200 # Node ID b38e888ee7e35e71d844706da075c4203c0e3268 # Parent e4c99610e1f72a7c960882a8f0758fca849e8208 no more using mx diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/ARPA.py --- a/embedded/mx/DateTime/ARPA.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,227 +0,0 @@ -""" This module provides a set of constructors and routines to convert - between DateTime[Delta] instances and ARPA representations of date - and time. The format is specified by RFC822 + RFC1123. - - Note: Timezones are only interpreted by ParseDateTimeGMT(). All - other constructors silently ignore the time zone information. - - Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. - -""" -import DateTime,Timezone -import re,string - -# Grammar: RFC822 + RFC1123 + depreciated RFC850 -_litday = '(?PMon|Tue|Wed|Thu|Fri|Sat|Sun)[a-z]*' -_litmonth = '(?PJan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'\ - '[a-z]*' -_date = ('(?:(?P\d?\d)(?: +' + _litmonth + - ' +|-(?P\d?\d)-)(?P(?:\d\d)?\d\d))') -_zone = Timezone.zone -_time = ('(?:(?P\d\d):(?P\d\d)' - '(?::(?P\d\d))?(?: +'+_zone+')?)') -# Timezone information is made optional because some mail apps -# forget to add it (most of these seem to be spamming engines, btw). -# It defaults to UTC. - -_arpadate = '(?:'+ _litday + ',? )? *' + _date -_arpadatetime = '(?:'+ _litday + ',? )? *' + _date + ' +' + _time - -# We are not strict about the extra characters: some applications -# add extra information to the date header field. Additional spaces -# between the fields and extra characters in the literal day -# and month fields are also silently ignored. - -arpadateRE = re.compile(_arpadate) -arpadatetimeRE = re.compile(_arpadatetime) - -# Translation tables -litdaytable = {'mon':0, 'tue':1, 'wed':2, 'thu':3, 'fri':4, 'sat':5, 'sun':6 } -litmonthtable = {'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6, - 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12 } -_days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] -_months = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] - -def ParseDate(arpastring,parse_arpadate=arpadateRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof, - lower=string.lower): - - """ParseDate(arpastring) - - Returns a DateTime instance reflecting the given ARPA - date. Only the date part is parsed, any time part will be - ignored. The instance's time is set to 0:00:00. - - """ - s = strip(arpastring) - date = parse_arpadate(s) - if not date: - raise ValueError,'wrong format' - litday,day,litmonth,month,year = date.groups() - if len(year) == 2: - year = DateTime.add_century(atoi(year)) - else: - year = atoi(year) - if litmonth: - litmonth = lower(litmonth) - try: - month = litmonthtable[litmonth] - except KeyError: - raise ValueError,'wrong month format' - else: - month = atoi(month) - day = atoi(day) - # litday and timezone are ignored - return DateTime.DateTime(year,month,day) - -def ParseDateTime(arpastring,parse_arpadatetime=arpadatetimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof, - lower=string.lower): - - """ParseDateTime(arpastring) - - Returns a DateTime instance reflecting the given ARPA date assuming - it is local time (timezones are silently ignored). - """ - s = strip(arpastring) - date = parse_arpadatetime(s) - if not date: - raise ValueError,'wrong format or unknown time zone' - litday,day,litmonth,month,year,hour,minute,second,zone = date.groups() - if len(year) == 2: - year = DateTime.add_century(atoi(year)) - else: - year = atoi(year) - if litmonth: - litmonth = lower(litmonth) - try: - month = litmonthtable[litmonth] - except KeyError: - raise ValueError,'wrong month format' - else: - month = atoi(month) - day = atoi(day) - hour = atoi(hour) - minute = atoi(minute) - if second is None: - second = 0.0 - else: - second = atof(second) - # litday and timezone are ignored - return DateTime.DateTime(year,month,day,hour,minute,second) - -def ParseDateTimeGMT(arpastring,parse_arpadatetime=arpadatetimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof, - lower=string.lower): - - """ParseDateTimeGMT(arpastring) - - Returns a DateTime instance reflecting the given ARPA date converting - it to UTC (timezones are honored). - """ - s = strip(arpastring) - date = parse_arpadatetime(s) - if not date: - raise ValueError,'wrong format or unknown time zone' - litday,day,litmonth,month,year,hour,minute,second,zone = date.groups() - if len(year) == 2: - year = DateTime.add_century(atoi(year)) - else: - year = atoi(year) - if litmonth: - litmonth = lower(litmonth) - try: - month = litmonthtable[litmonth] - except KeyError: - raise ValueError,'wrong month format' - else: - month = atoi(month) - day = atoi(day) - hour = atoi(hour) - minute = atoi(minute) - if second is None: - second = 0.0 - else: - second = atof(second) - offset = Timezone.utc_offset(zone) - # litday is ignored - return DateTime.DateTime(year,month,day,hour,minute,second) - offset - -# Alias -ParseDateTimeUTC = ParseDateTimeGMT - -def str(datetime,tz=None): - - """str(datetime,tz=DateTime.tz_offset(datetime)) - - Returns the datetime instance as ARPA date string. tz can be given - as DateTimeDelta instance providing the time zone difference from - datetime's zone to UTC. It defaults to - DateTime.tz_offset(datetime) which assumes local time. """ - - if tz is None: - tz = datetime.gmtoffset() - return '%s, %02i %s %04i %02i:%02i:%02i %+03i%02i' % ( - _days[datetime.day_of_week], datetime.day, - _months[datetime.month], datetime.year, - datetime.hour, datetime.minute, datetime.second, - tz.hour,tz.minute) - -def strGMT(datetime): - - """ strGMT(datetime) - - Returns the datetime instance as ARPA date string assuming it - is given in GMT. """ - - return '%s, %02i %s %04i %02i:%02i:%02i GMT' % ( - _days[datetime.day_of_week], datetime.day, - _months[datetime.month], datetime.year, - datetime.hour, datetime.minute, datetime.second) - -def strUTC(datetime): - - """ strUTC(datetime) - - Returns the datetime instance as ARPA date string assuming it - is given in UTC. """ - - return '%s, %02i %s %04i %02i:%02i:%02i UTC' % ( - _days[datetime.day_of_week], datetime.day, - _months[datetime.month], datetime.year, - datetime.hour, datetime.minute, datetime.second) - -def _test(): - import sys, os, rfc822 - file = os.path.join(os.environ['HOME'], 'nsmail/Inbox') - f = open(file, 'r') - while 1: - m = rfc822.Message(f) - if not m: - break - print 'From:', m.getaddr('from') - print 'To:', m.getaddrlist('to') - print 'Subject:', m.getheader('subject') - raw = m.getheader('date') - try: - date = ParseDateTimeUTC(raw) - print 'Date:',strUTC(date) - except ValueError,why: - print 'PROBLEMS:',repr(raw),'-->',why - raw_input('...hit return to continue') - print - # Netscape mail file - while 1: - line = f.readline() - if line[:6] == 'From -': - break - -if __name__ == '__main__': - _test() diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/DateTime.py --- a/embedded/mx/DateTime/DateTime.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1054 +0,0 @@ -""" Python part of the low-level DateTime[Delta] type implementation. - - Copyright (c) 1998-2001, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. -""" -# Import the python implementation module -from mxDateTime_python import * -from mxDateTime_python import __version__ - -# Singletons -oneSecond = DateTimeDelta(0,0,0,1) -oneMinute = DateTimeDelta(0,0,1) -oneHour = DateTimeDelta(0,1) -oneDay = DateTimeDelta(1) -oneWeek = DateTimeDelta(7) -Epoch = DateTimeFromAbsDateTime(1,0) - -# Shortcuts for pickle; for backward compatibility only (they are now -# defined in __init__.py to further reduce the pickles length) -def _DT(absdate,abstime): - return DateTimeFromAbsDateTime(absdate,abstime) -def _DTD(seconds): - return DateTimeDeltaFromSeconds(seconds) - -# Module init -class modinit: - - global _time,_string,_math,_types - import time,string,math,types - _time = time - _string = string - _math = math - _types = types - -del modinit - -### Helpers - -def _isstring(arg, - - isinstance=isinstance, types=_types): - - if isinstance(arg, types.StringType): - return 1 - try: - if isinstance(arg, types.UnicodeType): - return 1 - except AttributeError: - pass - return 0 - -### Compatibility APIs - -# Aliases and functions to make 'from mx.DateTime import *' work much -# like 'from time import *' - -def localtime(ticks=None, - # Locals: - time=_time.time,float=float,localtime=_time.localtime, - round=round,int=int,DateTime=DateTime,floor=_math.floor): - - """localtime(ticks=None) - - Construct a DateTime instance using local time from ticks. If - ticks are not given, it defaults to the current time. The - result is similar to time.localtime(). Fractions of a second - are rounded to the nearest micro-second. - - """ - if ticks is None: - ticks = time() - else: - ticks = float(ticks) - ticks = round(ticks, 6) - fticks = floor(ticks) - Y,M,D,h,m,s = localtime(fticks)[:6] - s = s + (ticks - fticks) - return DateTime(Y,M,D,h,m,s) - -def gmtime(ticks=None, - # Locals: - time=_time.time,float=float,gmtime=_time.gmtime, - round=round,int=int,DateTime=DateTime,floor=_math.floor): - - """gmtime(ticks=None) - - Construct a DateTime instance using UTC time from ticks. If - ticks are not given, it defaults to the current time. The - result is similar to time.gmtime(). Fractions of a second are - rounded to the nearest micro-second. - - """ - if ticks is None: - ticks = time() - else: - ticks = float(ticks) - ticks = round(ticks, 6) - fticks = floor(ticks) - Y,M,D,h,m,s = gmtime(ticks)[:6] - s = s + (ticks - fticks) - return DateTime(Y,M,D,h,m,s) - -def mktime((year,month,day,hour,minute,second,dow,doy,dst), - # Locals: - DateTime=DateTime): - - """mktime((year,month,day,hour,minute,second,dow,doy,dst)) - - Same as the DateTime() constructor accept that the interface - used is compatible to the similar time.mktime() API. - - Note that the tuple elements dow, doy and dst are not used in - any way. - - """ - return DateTime(year,month,day,hour,minute,second) - -def ctime(datetime): - - """ctime(datetime) - - Returns a string representation of the given DateTime instance - using the current locale's default settings. - - """ - return datetime.strftime('%c') - -def today(hour=0,minute=0,second=0.0, - # Locals: - localtime=_time.localtime,time=_time.time,DateTime=DateTime): - - """today(hour=0,minute=0,second=0.0) - - Returns a DateTime instance for today (in local time) at the - given time (defaults to midnight). - - """ - Y,M,D = localtime(time())[:3] - return DateTime(Y,M,D,hour,minute,second) - -def TimeDelta(hours=0.0,minutes=0.0,seconds=0.0, - # Locals: - DateTimeDelta=DateTimeDelta): - - """TimeDelta(hours=0.0,minutes=0.0,seconds=0.0) - - Returns a DateTimeDelta-object reflecting the given time - delta. Seconds can be given as float to indicate fractions. - - """ - return DateTimeDelta(0,hours,minutes,seconds) - -def gm2local(datetime): - - """ gm2local(datetime) - - Convert a DateTime instance holding UTC time to a DateTime - instance using local time. - - """ - return localtime(datetime.gmticks()) - -def local2gm(datetime): - - """ local2gm(datetime) - - Convert a DateTime instance holding local time to a DateTime - instance using UTC time. - - """ - return gmtime(datetime.ticks()) - -# Alias -gmt = utc - -# Default value for DateTimeFromTJD's tjd_myriad parameter -current_myriad = localtime().tjd_myriad - -def DateTimeFromTJD(tjd,tjd_myriad=current_myriad): - - """ DateTimeFromTJD(tjd[,myriad]) - - Return a DateTime instance for the given Truncated Julian Day. - myriad defaults to the TJD myriad current at package import - time. - - Note that this version of Truncated Julian Day number does - real truncation of important information. It's use is - discouraged and unsupported. - - """ - return DateTimeFromAbsDays(tjd + tjd_myriad * 10000.0 - 1721425.0) - -def DateTimeFromJDN(jdn): - - """ DateTimeFromJDN(jdn) - - Return a DateTime instance for the given Julian Day Number. - - References: - ----------- - Gregorian 2000-01-01 12:00:00 corresponds to JDN 2451545.0. - Gregorian 1858-11-17 00:00:00.00 corresponds to JDN 2400000.5; MJD 0.0. - Julian -4712-01-01 12:00:00.00 corresponds to JDN 0.0. - Gregorian -4713-11-24 12:00:00.00 corresponds to JDN 0.0. - - """ - return DateTimeFromAbsDays(jdn - 1721425.5) - -def DateTimeFromMJD(mjd): - - """ DateTimeFromMJD(mjd) - - Return a DateTime instance for the given Modified Julian Day - (MJD). The MJD is calculated the same way as the JDN except - that 1858-11-17 00:00:00.00 is taken as origin of the scale. - - """ - return DateTimeFromAbsDays(mjd + 678575.0) - -def DateTimeFrom(*args, **kws): - - """ DateTimeFrom(*args, **kws) - - Generic DateTime instance constructor. Can handle parsing - strings, numbers and keywords. - - XXX Add support for Unicode. - - """ - if len(args) == 1: - # Single argument - arg = args[0] - argtype = type(arg) - if _isstring(arg): - import Parser - return apply(Parser.DateTimeFromString, args, kws) - elif argtype is DateTimeType: - return arg - elif argtype is DateTimeDeltaType: - raise TypeError,'cannot convert DateTimeDelta to DateTime' - else: - try: - value = float(arg) - except (TypeError, ValueError): - value = int(arg) - assert not kws - return DateTimeFromTicks(value) - - elif len(args) > 1: - # More than one argument - if len(args) == 2 and _isstring(args[0]) and _isstring(args[1]): - # interpret as date and time string - import Parser - return apply(Parser.DateTimeFromString, - (args[0] + ' ' + args[1],), - kws) - - # Assume the arguments are the same as for DateTime() - return apply(DateTime, args, kws) - - elif len(kws) > 0: - # Keyword arguments; add defaults... today at 0:00:00 - hour = kws.get('hour',0) - minute = kws.get('minute',0) - second = kws.get('second',0) - today = now() - day = kws.get('day',today.day) - month = kws.get('month',today.month) - year = kws.get('year',today.year) - return DateTime(year,month,day,hour,minute,second) - - else: - raise TypeError,'cannot convert arguments to DateTime' - -def DateTimeDeltaFrom(*args, **kws): - - """ DateTimeDeltaFrom(*args, **kws) - - Generic DateTimeDelta instance constructor. Can handle parsing - strings, numbers and keywords. - - XXX Add support for Unicode. - - """ - if len(args) == 1: - # Single argument - arg = args[0] - if _isstring(arg): - import Parser - return apply(Parser.DateTimeDeltaFromString, args, kws) - elif type(arg) is DateTimeDeltaType: - return arg - elif type(arg) is DateTimeType: - raise TypeError,'cannot convert DateTime to DateTimeDelta' - else: - try: - value = float(arg) - except TypeError: - value = int(arg) - assert not kws - return DateTimeDeltaFromSeconds(value) - - elif len(args) > 1: - # Assume the arguments are the same as for DateTimeDelta() - return apply(DateTimeDelta, args, kws) - - elif len(kws) > 0: - # Keyword arguments; default: 00:00:00:00.00 - hours = kws.get('hours',0) - minutes = kws.get('minutes',0) - seconds = kws.get('seconds',0.0) - days = kws.get('days',0) - return DateTimeDelta(days,hours,minutes,seconds) - - else: - raise TypeError,'cannot convert arguments to DateTimeDelta' - -def TimeDeltaFrom(*args, **kws): - - """ TimeDeltaFrom(*args, **kws) - - Generic TimeDelta instance constructor. Can handle parsing - strings, numbers and keywords. - - XXX Add support for Unicode. - - """ - if len(args) > 1: - # Assume the arguments are the same as for TimeDelta(): without - # days part ! - return apply(DateTimeDelta, (0,)+args, kws) - else: - # Otherwise treat the arguments just like for DateTimeDelta - # instances. - return apply(DateTimeDeltaFrom, args, kws) - -def DateFromTicks(ticks, - # Locals: - DateTime=DateTime,localtime=_time.localtime): - - """ DateFromTicks(ticks) - - Constructs a DateTime instance pointing to the local time date - at 00:00:00.00 (midnight) indicated by the given ticks value. - The time part is ignored. - - """ - return apply(DateTime, localtime(ticks)[:3]) - -def TimestampFromTicks(ticks, - # Locals: - DateTime=DateTime,localtime=_time.localtime): - - """ TimestampFromTicks(ticks) - - Constructs a DateTime instance pointing to the local date and - time indicated by the given ticks value. - - """ - return apply(DateTime, localtime(ticks)[:6]) - -def TimeFromTicks(ticks, - # Locals: - DateTimeDelta=DateTimeDelta,localtime=_time.localtime): - - """ TimeFromTicks(ticks) - - Constructs a DateTimeDelta instance pointing to the local time - indicated by the given ticks value. The date part is ignored. - - """ - return apply(DateTimeDelta, (0,) + localtime(ticks)[3:6]) - -# Aliases -utctime = gmtime -utc2local = gm2local -local2utc = local2gm -DateTimeFromTicks = localtime -Date = DateTime -Time = TimeDelta -Timestamp = DateTime -DateFrom = DateTimeFrom # XXX should only parse the date part ! -TimeFrom = TimeDeltaFrom -TimestampFrom = DateTimeFrom -GregorianDateTime = DateTime -GregorianDate = Date -JulianDate = JulianDateTime - - -### For backward compatibility (these are depreciated): - -def gmticks(datetime): - - """gmticks(datetime) - - [DEPRECIATED: use the .gmticks() method] - - Returns a ticks value based on the values stored in - datetime under the assumption that they are given in UTC, - rather than local time. - - """ - return datetime.gmticks() - -# Alias -utcticks = gmticks - -def tz_offset(datetime, - # Locals: - oneSecond=oneSecond): - - """tz_offset(datetime) - - [DEPRECIATED: use the .gmtoffset() method] - - Returns a DateTimeDelta instance representing the UTC - offset for datetime assuming that the stored values refer - to local time. If you subtract this value from datetime, - you'll get UTC time. - - """ - return datetime.gmtoffset() - -### Constants (only English; see Locale.py for other languages) - -# Weekdays -Monday = 0 -Tuesday = 1 -Wednesday = 2 -Thursday = 3 -Friday = 4 -Saturday = 5 -Sunday = 6 -# as mapping -Weekday = {'Saturday': 5, 6: 'Sunday', 'Sunday': 6, 'Thursday': 3, - 'Wednesday': 2, 'Friday': 4, 'Tuesday': 1, 'Monday': 0, - 5: 'Saturday', 4: 'Friday', 3: 'Thursday', 2: 'Wednesday', - 1: 'Tuesday', 0: 'Monday'} - -# Months -January = 1 -February = 2 -March = 3 -April = 4 -May = 5 -June = 6 -July = 7 -August = 8 -September = 9 -October = 10 -November = 11 -December = 12 -# as mapping -Month = {2: 'February', 3: 'March', None: 0, 'July': 7, 11: 'November', - 'December': 12, 'June': 6, 'January': 1, 'September': 9, 'August': - 8, 'March': 3, 'November': 11, 'April': 4, 12: 'December', 'May': - 5, 10: 'October', 9: 'September', 8: 'August', 7: 'July', 6: - 'June', 5: 'May', 4: 'April', 'October': 10, 'February': 2, 1: - 'January', 0: None} - -# Limits (see also the range checks in mxDateTime.c) -MaxDateTime = DateTime(5867440,12,31) -MinDateTime = DateTime(-5851455,1,1) -MaxDateTimeDelta = DateTimeDeltaFromSeconds(2147483647 * 86400.0) -MinDateTimeDelta = -MaxDateTimeDelta - -### - -class RelativeDateTime: - - """RelativeDateTime(years=0,months=0,days=0, - hours=0,minutes=0,seconds=0, - year=0,month=0,day=0, - hour=None,minute=None,second=None, - weekday=None,weeks=None) - - Returns a RelativeDateTime instance for the specified relative - time. The constructor handles keywords, so you'll only have to - give those parameters which should be changed when you add the - relative to an absolute DateTime instance. - - Adding RelativeDateTime instances is supported with the - following rules: deltas will be added together, right side - absolute values override left side ones. - - Adding RelativeDateTime instances to DateTime instances will - return DateTime instances with the appropriate calculations - applied, e.g. to get a DateTime instance for the first of next - month, you'd call now() + RelativeDateTime(months=+1,day=1). - - """ - years = 0 - months = 0 - days = 0 - year = None - month = 0 - day = 0 - hours = 0 - minutes = 0 - seconds = 0 - hour = None - minute = None - second = None - weekday = None - - # cached hash value - _hash = None - - # For Zope security: - __roles__ = None - __allow_access_to_unprotected_subobjects__ = 1 - - def __init__(self, - years=0,months=0,days=0, - hours=0,minutes=0,seconds=0, - year=None,month=None,day=None, - hour=None,minute=None,second=None, - weekday=None,weeks=0): - - self.years = years - self.months = months - self.days = days + weeks*7 - self.year = year - self.month = month - self.day = day - self.hours = hours - self.minutes = minutes - self.seconds = seconds - self.hour = hour - self.minute = minute - self.second = second - if weekday is not None: - # Make sure we've got a 2-tuple - assert len(weekday) == 2 - self.weekday = weekday - - def __add__(self,other, - # Locals: - isinstance=isinstance): - - if isinstance(other,RelativeDateTime): - # RelativeDateTime (self) + RelativeDateTime (other) - - r = RelativeDateTime() - # date deltas - r.years = self.years + other.years - r.months = self.months + other.months - r.days = self.days + other.days - # absolute entries of other override those in self, if given - r.year = other.year or self.year - r.month = other.month or self.month - r.day = other.day or self.day - r.weekday = other.weekday or self.weekday - # time deltas - r.hours = self.hours + other.hours - r.minutes = self.minutes + other.minutes - r.seconds = self.seconds + other.seconds - # absolute entries of other override those in self, if given - r.hour = other.hour or self.hour - r.minute = other.minute or self.minute - r.second = other.second or self.second - return r - - else: - raise TypeError,"can't add the two types" - - def __radd__(self,other, - # Locals: - isinstance=isinstance,DateTimeType=DateTimeType, - DateTime=DateTime,DateTimeDelta=DateTimeDelta): - - if isinstance(other,DateTimeType): - # DateTime (other) + RelativeDateTime (self) - - # date - if self.year is None: - year = other.year + self.years - else: - year = self.year + self.years - if self.month is None: - month = other.month + self.months - else: - month = self.month + self.months - if self.day is None: - day = other.day - else: - day = self.day - if day < 0: - # fix negative day values - month = month + 1 - day = day + 1 - day = day + self.days - # time - if self.hour is None: - hour = other.hour + self.hours - else: - hour = self.hour + self.hours - if self.minute is None: - minute = other.minute + self.minutes - else: - minute = self.minute + self.minutes - if self.second is None: - second = other.second + self.seconds - else: - second = self.second + self.seconds - - # Refit into proper ranges: - if month < 1 or month > 12: - month = month - 1 - yeardelta, monthdelta = divmod(month, 12) - year = year + yeardelta - month = monthdelta + 1 - - # Make sure we have integers - year = int(year) - month = int(month) - day = int(day) - - if self.weekday is None: - return DateTime(year, month, 1) + \ - DateTimeDelta(day-1,hour,minute,second) - - # Adjust to the correct weekday - day_of_week,index = self.weekday - d = DateTime(year, month, 1) + \ - DateTimeDelta(day-1,hour,minute,second) - if index == 0: - # 0 index: next weekday if no match - return d + (day_of_week - d.day_of_week) - elif index > 0: - # positive index (1 == first weekday of month) - first = d - (d.day - 1) - diff = day_of_week - first.day_of_week - if diff >= 0: - return first + (diff + (index-1) * 7) - else: - return first + (diff + index * 7) - else: - # negative index (-1 == last weekday of month) - last = d + (d.days_in_month - d.day) - diff = day_of_week - last.day_of_week - if diff <= 0: - return last + (diff + (index+1) * 7) - else: - return last + (diff + index * 7) - - else: - raise TypeError,"can't add the two types" - - def __sub__(self,other): - - if isinstance(other,RelativeDateTime): - # RelativeDateTime (self) - RelativeDateTime (other) - - r = RelativeDateTime() - # date deltas - r.years = self.years - other.years - r.months = self.months - other.months - r.days = self.days - other.days - # absolute entries of other override those in self, if given - r.year = other.year or self.year - r.month = other.month or self.month - r.day = other.day or self.day - r.weekday = other.weekday or self.weekday - # time deltas - r.hours = self.hours - other.hours - r.minutes = self.minutes - other.minutes - r.seconds = self.seconds - other.seconds - # absolute entries of other override those in self, if given - r.hour = other.hour or self.hour - r.minute = other.minute or self.minute - r.second = other.second or self.second - - return r - - else: - raise TypeError,"can't subtract the two types" - - def __rsub__(self,other, - # Locals: - isinstance=isinstance,DateTimeType=DateTimeType): - - if isinstance(other,DateTimeType): - # DateTime (other) - RelativeDateTime (self) - return other + self.__neg__() - - else: - raise TypeError,"can't subtract the two types" - - def __neg__(self): - - # - RelativeDateTime(self) - - r = RelativeDateTime() - # negate date deltas - r.years = - self.years - r.months = - self.months - r.days = - self.days - # absolute entries don't change - r.year = self.year - r.month = self.month - r.day = self.day - r.weekday = self.weekday - # negate time deltas - r.hours = - self.hours - r.minutes = - self.minutes - r.seconds = - self.seconds - # absolute entries don't change - r.hour = self.hour - r.minute = self.minute - r.second = self.second - - return r - - def __nonzero__(self): - - # RelativeDateTime instances are considered false in case - # they do not define any alterations - if (self.year is None and - self.years == 0 and - self.month is None and - self.months == 0 and - self.day is None and - self.weekday is None and - self.days == 0 and - self.hour is None and - self.hours == 0 and - self.minute is None and - self.minutes == 0 and - self.second is None and - self.seconds == 0): - return 0 - else: - return 1 - - def __mul__(self,other): - - # RelativeDateTime (self) * Number (other) - factor = float(other) - - r = RelativeDateTime() - # date deltas - r.years = factor * self.years - r.months = factor * self.months - r.days = factor * self.days - # time deltas - r.hours = factor * self.hours - r.minutes = factor * self.minutes - r.seconds = factor * self.seconds - return r - - __rmul__ = __mul__ - - def __div__(self,other): - - # RelativeDateTime (self) / Number (other) - return self.__mul__(1/float(other)) - - def __eq__(self, other): - - if isinstance(self, RelativeDateTime) and \ - isinstance(other, RelativeDateTime): - # RelativeDateTime (self) == RelativeDateTime (other) - if (self.years == other.years and - self.months == other.months and - self.days == other.days and - self.year == other.year and - self.day == other.day and - self.hours == other.hours and - self.minutes == other.minutes and - self.seconds == other.seconds and - self.hour == other.hour and - self.minute == other.minute and - self.second == other.second and - self.weekday == other.weekday): - return 1 - else: - return 0 - else: - raise TypeError,"can't compare the two types" - - def __hash__(self): - - if self._hash is not None: - return self._hash - x = 1234 - for value in (self.years, self.months, self.days, - self.year, self.day, - self.hours, self.minutes, self.seconds, - self.hour, self.minute, self.second, - self.weekday): - if value is None: - x = 135051820 ^ x - else: - x = hash(value) ^ x - self._hash = x - return x - - def __str__(self, - - join=_string.join): - - l = [] - append = l.append - - # Format date part - if self.year is not None: - append('%04i-' % self.year) - elif self.years: - append('(%0+5i)-' % self.years) - else: - append('YYYY-') - if self.month is not None: - append('%02i-' % self.month) - elif self.months: - append('(%0+3i)-' % self.months) - else: - append('MM-') - if self.day is not None: - append('%02i' % self.day) - elif self.days: - append('(%0+3i)' % self.days) - else: - append('DD') - if self.weekday: - append(' %s:%i' % (Weekday[self.weekday[0]][:3],self.weekday[1])) - append(' ') - - # Normalize relative time values to avoid fractions - hours = self.hours - minutes = self.minutes - seconds = self.seconds - hours_fraction = hours - int(hours) - minutes = minutes + hours_fraction * 60.0 - minutes_fraction = minutes - int(minutes) - seconds = seconds + minutes_fraction * 6.0 - seconds_fraction = seconds - int(seconds) - - if 0: - # Normalize to standard time ranges - if seconds > 60.0: - extra_minutes, seconds = divmod(seconds, 60.0) - minutes = minutes + extra_minutes - elif seconds < -60.0: - extra_minutes, seconds = divmod(seconds, -60.0) - minutes = minutes - extra_minutes - if minutes >= 60.0: - extra_hours, minutes = divmod(minutes, 60.0) - hours = hours + extra_hours - elif minutes <= -60.0: - extra_hours, minutes = divmod(minutes, -60.0) - hours = hours - extra_hours - - # Format time part - if self.hour is not None: - append('%02i:' % self.hour) - elif hours: - append('(%0+3i):' % hours) - else: - append('HH:') - if self.minute is not None: - append('%02i:' % self.minute) - elif minutes: - append('(%0+3i):' % minutes) - else: - append('MM:') - if self.second is not None: - append('%02i' % self.second) - elif seconds: - append('(%0+3i)' % seconds) - else: - append('SS') - - return join(l,'') - - def __repr__(self): - - return "<%s instance for '%s' at 0x%x>" % ( - self.__class__.__name__, - self.__str__(), - id(self)) - -# Alias -RelativeDate = RelativeDateTime - -def RelativeDateTimeFrom(*args, **kws): - - """ RelativeDateTimeFrom(*args, **kws) - - Generic RelativeDateTime instance constructor. Can handle - parsing strings and keywords. - - """ - if len(args) == 1: - # Single argument - arg = args[0] - if _isstring(arg): - import Parser - return apply(Parser.RelativeDateTimeFromString, args, kws) - elif isinstance(arg, RelativeDateTime): - return arg - else: - raise TypeError,\ - 'cannot convert argument to RelativeDateTime' - - else: - return apply(RelativeDateTime,args,kws) - -def RelativeDateTimeDiff(date1,date2, - - floor=_math.floor,int=int,divmod=divmod, - RelativeDateTime=RelativeDateTime): - - """ RelativeDateTimeDiff(date1,date2) - - Returns a RelativeDateTime instance representing the difference - between date1 and date2 in relative terms. - - The following should hold: - - date2 + RelativeDateDiff(date1,date2) == date1 - - for all dates date1 and date2. - - Note that due to the algorithm used by this function, not the - whole range of DateTime instances is supported; there could - also be a loss of precision. - - XXX There are still some problems left (thanks to Carel - Fellinger for pointing these out): - - 29 1 1901 -> 1 3 1901 = 1 month - 29 1 1901 -> 1 3 1900 = -10 month and -28 days, but - 29 1 1901 -> 28 2 1900 = -11 month and -1 day - - and even worse: - - >>> print RelativeDateDiff(Date(1900,3,1),Date(1901,2,1)) - YYYY-(-11)-DD HH:MM:SS - - with: - - >>> print Date(1901,1,29) + RelativeDateTime(months=-11) - 1900-03-01 00:00:00.00 - >>> print Date(1901,2,1) + RelativeDateTime(months=-11) - 1900-03-01 00:00:00.00 - - """ - diff = date1 - date2 - if diff.days == 0: - return RelativeDateTime() - date1months = date1.year * 12 + (date1.month - 1) - date2months = date2.year * 12 + (date2.month - 1) - #print 'months',date1months,date2months - - # Calculate the months difference - diffmonths = date1months - date2months - #print 'diffmonths',diffmonths - if diff.days > 0: - years,months = divmod(diffmonths,12) - else: - years,months = divmod(diffmonths,-12) - years = -years - date3 = date2 + RelativeDateTime(years=years,months=months) - diff3 = date1 - date3 - days = date1.absdays - date3.absdays - #print 'date3',date3,'diff3',diff3,'days',days - - # Correction to ensure that all relative parts have the same sign - while days * diff.days < 0: - if diff.days > 0: - diffmonths = diffmonths - 1 - years,months = divmod(diffmonths,12) - else: - diffmonths = diffmonths + 1 - years,months = divmod(diffmonths,-12) - years = -years - #print 'diffmonths',diffmonths - date3 = date2 + RelativeDateTime(years=years,months=months) - diff3 = date1 - date3 - days = date1.absdays - date3.absdays - #print 'date3',date3,'diff3',diff3,'days',days - - # Drop the fraction part of days - if days > 0: - days = int(floor(days)) - else: - days = int(-floor(-days)) - - return RelativeDateTime(years=years, - months=months, - days=days, - hours=diff3.hour, - minutes=diff3.minute, - seconds=diff3.second) - -# Aliases -RelativeDateDiff = RelativeDateTimeDiff -Age = RelativeDateTimeDiff - -### - -_current_year = now().year -_current_century, _current_year_in_century = divmod(_current_year, 100) -_current_century = _current_century * 100 - -def add_century(year, - - current_year=_current_year, - current_century=_current_century): - - """ Sliding window approach to the Y2K problem: adds a suitable - century to the given year and returns it as integer. - - The window used depends on the current year (at import time). - If adding the current century to the given year gives a year - within the range current_year-70...current_year+30 [both - inclusive], then the current century is added. Otherwise the - century (current + 1 or - 1) producing the least difference is - chosen. - - """ - if year > 99: - # Take it as-is - return year - year = year + current_century - diff = year - current_year - if diff >= -70 and diff <= 30: - return year - elif diff < -70: - return year + 100 - else: - return year - 100 - -# Reference formulas for JDN taken from the Calendar FAQ: - -def gregorian_jdn(year,month,day): - - # XXX These require proper integer division. - a = (14-month)/12 - y = year+4800-a - m = month + 12*a - 3 - return day + (306*m+5)/10 + y*365 + y/4 - y/100 + y/400 - 32045 - -def julian_jdn(year,month,day): - - # XXX These require proper integer division. - a = (14-month)/12 - y = year+4800-a - m = month + 12*a - 3 - return day + (306*m+5)/10 + y*365 + y/4 - 32083 diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/ISO.py --- a/embedded/mx/DateTime/ISO.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,366 +0,0 @@ -""" This module provides a set of constructors and routines to convert - between DateTime[Delta] instances and ISO representations of date - and time. - - Note: Timezones are only interpreted by ParseDateTimeGMT(). All - other constructors silently ignore the time zone information. - - Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. - -""" -import DateTime,Timezone -import re,string - -# Grammar: ISO 8601 (not all, but what we need from it) -_year = '(?P\d?\d\d\d)' -_month = '(?P\d?\d)' -_day = '(?P\d?\d)' -_hour = '(?P\d?\d)' -_minute = '(?P\d?\d)' -_second = '(?P\d?\d(?:\.\d+)?)' -_sign = '(?P[-+])' -_week = 'W(?P\d?\d)' -_zone = Timezone.isozone - -_weekdate = _year + '-?(?:' + _week + '-?' + _day + '?)?' -_date = _year + '-?' + '(?:' + _month + '-?' + _day + '?)?' -_time = _hour + ':?' + _minute + ':?' + _second + '?(?:' + _zone + ')?' - -isodatetimeRE = re.compile(_date + '(?:[ T]' + _time + ')?$') -isodateRE = re.compile(_date + '$') -isotimeRE = re.compile(_time + '$') -isodeltaRE = re.compile(_sign + '?' + _time + '$') -isoweekRE = re.compile(_weekdate + '$') -isoweektimeRE = re.compile(_weekdate + '(?:[ T]' + _time + ')?$') - -def WeekTime(year,isoweek=1,isoday=1,hour=0,minute=0,second=0.0): - - """Week(year,isoweek=1,isoday=1,hour=0,minute=0,second=0.0) - - Returns a DateTime instance pointing to the given ISO week and - day. isoday defaults to 1, which corresponds to Monday in the - ISO numbering. The time part is set as given. - - """ - d = DateTime.DateTime(year,1,1,hour,minute,second) - if d.iso_week[0] == year: - # 1.1. belongs to year (backup to Monday) - return d + (-d.day_of_week + 7 * (isoweek-1) + isoday-1) - else: - # 1.1. belongs to year-1 (advance to next Monday) - return d + (7-d.day_of_week + 7 * (isoweek-1) + isoday-1) - -# Alias -Week = WeekTime - -# Aliases for the other constructors (they all happen to already use -# ISO format) -Date = DateTime.Date -Time = DateTime.Time -TimeDelta = DateTime.TimeDelta - -def ParseDateTime(isostring,parse_isodatetime=isodatetimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseDateTime(isostring) - - Returns a DateTime instance reflecting the given ISO date. A - time part is optional and must be delimited from the date by a - space or 'T'. - - Time zone information is parsed, but not evaluated. - - """ - s = strip(isostring) - date = parse_isodatetime(s) - if not date: - raise ValueError,'wrong format, use YYYY-MM-DD HH:MM:SS' - year,month,day,hour,minute,second,zone = date.groups() - year = atoi(year) - if month is None: - month = 1 - else: - month = atoi(month) - if day is None: - day = 1 - else: - day = atoi(day) - if hour is None: - hour = 0 - else: - hour = atoi(hour) - if minute is None: - minute = 0 - else: - minute = atoi(minute) - if second is None: - second = 0.0 - else: - second = atof(second) - return DateTime.DateTime(year,month,day,hour,minute,second) - -def ParseDateTimeGMT(isostring,parse_isodatetime=isodatetimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseDateTimeGMT(isostring) - - Returns a DateTime instance in UTC reflecting the given ISO - date. A time part is optional and must be delimited from the - date by a space or 'T'. Timezones are honored. - - """ - s = strip(isostring) - date = parse_isodatetime(s) - if not date: - raise ValueError,'wrong format, use YYYY-MM-DD HH:MM:SS' - year,month,day,hour,minute,second,zone = date.groups() - year = atoi(year) - if month is None: - month = 1 - else: - month = atoi(month) - if day is None: - day = 1 - else: - day = atoi(day) - if hour is None: - hour = 0 - else: - hour = atoi(hour) - if minute is None: - minute = 0 - else: - minute = atoi(minute) - if second is None: - second = 0.0 - else: - second = atof(second) - offset = Timezone.utc_offset(zone) - return DateTime.DateTime(year,month,day,hour,minute,second) - offset - -# Alias -ParseDateTimeUTC = ParseDateTimeGMT - -def ParseDate(isostring,parse_isodate=isodateRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseDate(isostring) - - Returns a DateTime instance reflecting the given ISO date. A - time part may not be included. - - """ - s = strip(isostring) - date = parse_isodate(s) - if not date: - raise ValueError,'wrong format, use YYYY-MM-DD' - year,month,day = date.groups() - year = atoi(year) - if month is None: - month = 1 - else: - month = atoi(month) - if day is None: - day = 1 - else: - day = atoi(day) - return DateTime.DateTime(year,month,day) - -def ParseWeek(isostring,parse_isoweek=isoweekRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseWeek(isostring) - - Returns a DateTime instance reflecting the given ISO date. A - time part may not be included. - - """ - s = strip(isostring) - date = parse_isoweek(s) - if not date: - raise ValueError,'wrong format, use yyyy-Www-d, e.g. 1998-W01-1' - year,week,day = date.groups() - year = atoi(year) - if week is None: - week = 1 - else: - week = atoi(week) - if day is None: - day = 1 - else: - day = atoi(day) - return Week(year,week,day) - -def ParseWeekTime(isostring,parse_isoweektime=isoweektimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseWeekTime(isostring) - - Returns a DateTime instance reflecting the given ISO date. A - time part is optional and must be delimited from the date by a - space or 'T'. - - """ - s = strip(isostring) - date = parse_isoweektime(s) - if not date: - raise ValueError,'wrong format, use e.g. "1998-W01-1 12:00:30"' - year,week,day,hour,minute,second,zone = date.groups() - year = atoi(year) - if week is None: - week = 1 - else: - week = atoi(week) - if day is None: - day = 1 - else: - day = atoi(day) - if hour is None: - hour = 0 - else: - hour = atoi(hour) - if minute is None: - minute = 0 - else: - minute = atoi(minute) - if second is None: - second = 0.0 - else: - second = atof(second) - return WeekTime(year,week,day,hour,minute,second) - -def ParseTime(isostring,parse_isotime=isotimeRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseTime(isostring) - - Returns a DateTimeDelta instance reflecting the given ISO time. - Hours and minutes must be given, seconds are - optional. Fractions of a second may also be used, - e.g. 12:23:12.34. - - """ - s = strip(isostring) - time = parse_isotime(s) - if not time: - raise ValueError,'wrong format, use HH:MM:SS' - hour,minute,second,zone = time.groups() - hour = atoi(hour) - minute = atoi(minute) - if second is not None: - second = atof(second) - else: - second = 0.0 - return DateTime.TimeDelta(hour,minute,second) - -def ParseTimeDelta(isostring,parse_isodelta=isodeltaRE.match, - - strip=string.strip,atoi=string.atoi,atof=string.atof): - - """ParseTimeDelta(isostring) - - Returns a DateTimeDelta instance reflecting the given ISO time - as delta. Hours and minutes must be given, seconds are - optional. Fractions of a second may also be used, - e.g. 12:23:12.34. In addition to the ISO standard a sign may be - prepended to the time, e.g. -12:34. - - """ - s = strip(isostring) - time = parse_isodelta(s) - if not time: - raise ValueError,'wrong format, use [-]HH:MM:SS' - sign,hour,minute,second,zone = time.groups() - hour = atoi(hour) - minute = atoi(minute) - if second is not None: - second = atof(second) - else: - second = 0.0 - if sign and sign == '-': - return -DateTime.TimeDelta(hour,minute,second) - else: - return DateTime.TimeDelta(hour,minute,second) - -def ParseAny(isostring): - - """ParseAny(isostring) - - Parses the given string and tries to convert it to a - DateTime[Delta] instance. - - """ - try: - return ParseDateTime(isostring) - except ValueError: - pass - try: - return ParseWeekTime(isostring) - except ValueError: - pass - try: - return ParseTimeDelta(isostring) - except ValueError: - raise ValueError,'unsupported format: "%s"' % isostring - -def str(datetime,tz=None): - - """str(datetime,tz=DateTime.tz_offset(datetime)) - - Returns the datetime instance as ISO date string. tz can be - given as DateTimeDelta instance providing the time zone - difference from datetime's zone to UTC. It defaults to - DateTime.tz_offset(datetime) which assumes local time. - - """ - if tz is None: - tz = datetime.gmtoffset() - return '%04i-%02i-%02i %02i:%02i:%02i%+03i%02i' % ( - datetime.year, datetime.month, datetime.day, - datetime.hour, datetime.minute, datetime.second, - tz.hour,tz.minute) - -def strGMT(datetime): - - """strGMT(datetime) - - Returns the datetime instance as ISO date string assuming it is - given in GMT. - - """ - return '%04i-%02i-%02i %02i:%02i:%02i+0000' % ( - datetime.year, datetime.month, datetime.day, - datetime.hour, datetime.minute, datetime.second) - -def strUTC(datetime): - - """strUTC(datetime) - - Returns the datetime instance as ISO date string assuming it is - given in UTC. - - """ - return '%04i-%02i-%02i %02i:%02i:%02i+0000' % ( - datetime.year, datetime.month, datetime.day, - datetime.hour, datetime.minute, datetime.second) - -# Testing -if __name__ == '__main__': - e = DateTime.Date(1900,1,1) - for i in range(100000): - d = e + i - year,week,day = d.iso_week - c = WeekTime(year,week,day) - if d != c: - print ' Check %s (given; %i) != %s (parsed)' % (d,d.day_of_week,c) - elif i % 1000 == 0: - print d,'ok' diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/Parser.py --- a/embedded/mx/DateTime/Parser.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1225 +0,0 @@ -# -*- coding: latin-1 -*- - -""" Date/Time string parsing module. - - Note about the Y2K problems: - - The parser can only handle years with at least 2 digits. 2 - digit year values get expanded by adding the century using - DateTime.add_century(), while 3 digit year get converted - literally. To have 2 digit years also be interpreted literally, - add leading zeros, e.g. year 99 must be written as 099 or 0099. - - Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. - -""" -import types,re,string -import DateTime,ISO,ARPA,Timezone - -# Enable to produce debugging output -_debug = 0 - -# REs for matching date and time parts in a string; These REs -# parse a superset of ARPA, ISO, American and European style dates. -# Timezones are supported via the Timezone submodule. - -_year = '(?P-?\d+\d(?!:))' -_fullyear = '(?P-?\d+\d\d(?!:))' -_year_epoch = '(?:' + _year + '(?P *[ABCDE\.]+)?)' -_fullyear_epoch = '(?:' + _fullyear + '(?P *[ABCDE\.]+)?)' -_relyear = '(?:\((?P[-+]?\d+)\))' - -_month = '(?P\d?\d(?!:))' -_fullmonth = '(?P\d\d(?!:))' -_litmonth = ('(?P' - 'jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec|' - 'mär|mae|mrz|mai|okt|dez|' - 'fev|avr|juin|juil|aou|aoû|déc|' - 'ene|abr|ago|dic|' - 'out' - ')[a-z,\.;]*') -litmonthtable = { - # English - 'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6, - 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12, - # German - 'mär':3, 'mae':3, 'mrz':3, 'mai':5, 'okt':10, 'dez':12, - # French - 'fev':2, 'avr':4, 'juin':6, 'juil':7, 'aou':8, 'aoû':8, - 'déc':12, - # Spanish - 'ene':1, 'abr':4, 'ago':8, 'dic':12, - # Portuguese - 'out':10, - } -_relmonth = '(?:\((?P[-+]?\d+)\))' - -_day = '(?P\d?\d(?!:))' -_usday = '(?P\d?\d(?!:))(?:st|nd|rd|th|[,\.;])?' -_fullday = '(?P\d\d(?!:))' -_litday = ('(?P' - 'mon|tue|wed|thu|fri|sat|sun|' - 'die|mit|don|fre|sam|son|' - 'lun|mar|mer|jeu|ven|sam|dim|' - 'mie|jue|vie|sab|dom|' - 'pri|seg|ter|cua|qui' - ')[a-z]*') -litdaytable = { - # English - 'mon':0, 'tue':1, 'wed':2, 'thu':3, 'fri':4, 'sat':5, 'sun':6, - # German - 'die':1, 'mit':2, 'don':3, 'fre':4, 'sam':5, 'son':6, - # French - 'lun':0, 'mar':1, 'mer':2, 'jeu':3, 'ven':4, 'sam':5, 'dim':6, - # Spanish - 'mie':2, 'jue':3, 'vie':4, 'sab':5, 'dom':6, - # Portuguese - 'pri':0, 'seg':1, 'ter':2, 'cua':3, 'qui':4, - } -_relday = '(?:\((?P[-+]?\d+)\))' - -_hour = '(?P[012]?\d)' -_minute = '(?P[0-6]\d)' -_second = '(?P[0-6]\d(?:[.,]\d+)?)' - -_days = '(?P\d*\d(?:[.,]\d+)?)' -_hours = '(?P\d*\d(?:[.,]\d+)?)' -_minutes = '(?P\d*\d(?:[.,]\d+)?)' -_seconds = '(?P\d*\d(?:[.,]\d+)?)' - -_reldays = '(?:\((?P[-+]?\d+(?:[.,]\d+)?)\))' -_relhours = '(?:\((?P[-+]?\d+(?:[.,]\d+)?)\))' -_relminutes = '(?:\((?P[-+]?\d+(?:[.,]\d+)?)\))' -_relseconds = '(?:\((?P[-+]?\d+(?:[.,]\d+)?)\))' - -_sign = '(?:(?P[-+]) *)' -_week = 'W(?P\d?\d)' -_zone = Timezone.zone -_ampm = '(?P[ap][m.]+)' - -_time = (_hour + ':' + _minute + '(?::' + _second + '|[^:]|$) *' - + _ampm + '? *' + _zone + '?') -_isotime = _hour + ':?' + _minute + ':?' + _second + '? *' + _zone + '?' - -_weekdate = _year + '-?(?:' + _week + '-?' + _day + '?)?' -_eurodate = _day + '\.' + _month + '\.' + _year_epoch + '?' -_usdate = _month + '/' + _day + '(?:/' + _year_epoch + '|[^/]|$)' -_altusdate = _month + '-' + _day + '-' + _fullyear_epoch -_isodate = _year + '-' + _month + '-?' + _day + '?(?!:)' -_altisodate = _year + _fullmonth + _fullday + '(?!:)' -_usisodate = _fullyear + '/' + _fullmonth + '/' + _fullday -_litdate = ('(?:'+ _litday + ',? )? *' + - _usday + ' *' + - '[- ] *(?:' + _litmonth + '|'+ _month +') *[- ] *' + - _year_epoch + '?') -_altlitdate = ('(?:'+ _litday + ',? )? *' + - _litmonth + '[ ,.a-z]+' + - _usday + - '(?:[ a-z]+' + _year_epoch + ')?') -_eurlitdate = ('(?:'+ _litday + ',?[ a-z]+)? *' + - '(?:'+ _usday + '[ a-z]+)? *' + - _litmonth + - '(?:[ ,.a-z]+' + _year_epoch + ')?') - -_relany = '[*%?a-zA-Z]+' - -_relisodate = ('(?:(?:' + _relany + '|' + _year + '|' + _relyear + ')-' + - '(?:' + _relany + '|' + _month + '|' + _relmonth + ')-' + - '(?:' + _relany + '|' + _day + '|' + _relday + '))') - -_asctime = ('(?:'+ _litday + ',? )? *' + - _usday + ' *' + - '[- ] *(?:' + _litmonth + '|'+ _month +') *[- ]' + - '(?:[0-9: ]+)' + - _year_epoch + '?') - -_relisotime = ('(?:(?:' + _relany + '|' + _hour + '|' + _relhours + '):' + - '(?:' + _relany + '|' + _minute + '|' + _relminutes + ')' + - '(?::(?:' + _relany + '|' + _second + '|' + _relseconds + '))?)') - -_isodelta1 = (_sign + '?' + - _days + ':' + _hours + ':' + _minutes + ':' + _seconds) -_isodelta2 = (_sign + '?' + - _hours + ':' + _minutes + ':' + _seconds) -_isodelta3 = (_sign + '?' + - _hours + ':' + _minutes) -_litdelta = (_sign + '?' + - '(?:' + _days + ' *d[a-z]*[,; ]*)?' + - '(?:' + _hours + ' *h[a-z]*[,; ]*)?' + - '(?:' + _minutes + ' *m[a-z]*[,; ]*)?' + - '(?:' + _seconds + ' *s[a-z]*[,; ]*)?') -_litdelta2 = (_sign + '?' + - '(?:' + _days + ' *d[a-z]*[,; ]*)?' + - _hours + ':' + _minutes + '(?::' + _seconds + ')?') - -_timeRE = re.compile(_time, re.I) -_isotimeRE = re.compile(_isotime, re.I) -_isodateRE = re.compile(_isodate, re.I) -_altisodateRE = re.compile(_altisodate, re.I) -_usisodateRE = re.compile(_usisodate, re.I) -_eurodateRE = re.compile(_eurodate, re.I) -_usdateRE = re.compile(_usdate, re.I) -_altusdateRE = re.compile(_altusdate, re.I) -_litdateRE = re.compile(_litdate, re.I) -_altlitdateRE = re.compile(_altlitdate, re.I) -_eurlitdateRE = re.compile(_eurlitdate, re.I) -_relisodateRE = re.compile(_relisodate, re.I) -_asctimeRE = re.compile(_asctime, re.I) -_isodelta1RE = re.compile(_isodelta1) -_isodelta2RE = re.compile(_isodelta2) -_isodelta3RE = re.compile(_isodelta3) -_litdeltaRE = re.compile(_litdelta) -_litdelta2RE = re.compile(_litdelta2) -_relisotimeRE = re.compile(_relisotime, re.I) - -# Available date parsers -_date_formats = ('euro', - 'usiso', 'us', 'altus', - 'iso', 'altiso', - 'lit', 'altlit', 'eurlit', - 'unknown') - -# Available time parsers -_time_formats = ('standard', - 'iso', - 'unknown') - -def _parse_date(text, formats=_date_formats, defaultdate=None, - - int=int,float=float,lower=string.lower, - add_century=DateTime.add_century, - now=DateTime.now,us_formats=('us', 'altus'), - iso_formats=('iso', 'altiso', 'usiso')): - - """ Parses the date part given in text and returns a tuple - (text,day,month,year,style) with the following - meanings: - - * text gives the original text without the date part - - * day,month,year give the parsed date - - * style gives information about which parser was successful: - 'euro' - the European date parser - 'us' - the US date parser - 'altus' - the alternative US date parser (with '-' instead of '/') - 'iso' - the ISO date parser - 'altiso' - the alternative ISO date parser (without '-') - 'usiso' - US style ISO date parser (yyyy/mm/dd) - 'lit' - the US literal date parser - 'altlit' - the alternative US literal date parser - 'eurlit' - the Eurpean literal date parser - 'unknown' - no date part was found, defaultdate was used - - formats may be set to a tuple of style strings specifying - which of the above parsers to use and in which order to try - them. Default is to try all of them in the above order. - - defaultdate provides the defaults to use in case no date part - is found. Most other parsers default to the current year - January 1 if some of these date parts are missing. - - If 'unknown' is not given in formats and the date cannot be - parsed, a ValueError is raised. - - """ - match = None - style = '' - - # Apply parsers in the order given in formats - for format in formats: - - if format == 'euro': - # European style date - match = _eurodateRE.search(text) - if match is not None: - day,month,year,epoch = match.groups() - if year: - if len(year) == 2: - # Y2K problem: - year = add_century(int(year)) - else: - year = int(year) - else: - if defaultdate is None: - defaultdate = now() - year = defaultdate.year - if epoch and 'B' in epoch: - year = -year + 1 - month = int(month) - day = int(day) - # Could have mistaken euro format for us style date - # which uses month, day order - if month > 12 or month == 0: - match = None - continue - break - - elif format in iso_formats: - # ISO style date - if format == 'iso': - match = _isodateRE.search(text) - elif format == 'altiso': - match = _altisodateRE.search(text) - # Avoid mistaking ISO time parts ('Thhmmss') for dates - if match is not None: - left, right = match.span() - if left > 0 and \ - text[left - 1:left] == 'T': - match = None - continue - else: - match = _usisodateRE.search(text) - if match is not None: - year,month,day = match.groups() - if len(year) == 2: - # Y2K problem: - year = add_century(int(year)) - else: - year = int(year) - # Default to January 1st - if not month: - month = 1 - else: - month = int(month) - if not day: - day = 1 - else: - day = int(day) - break - - elif format in us_formats: - # US style date - if format == 'us': - match = _usdateRE.search(text) - else: - match = _altusdateRE.search(text) - if match is not None: - month,day,year,epoch = match.groups() - if year: - if len(year) == 2: - # Y2K problem: - year = add_century(int(year)) - else: - year = int(year) - else: - if defaultdate is None: - defaultdate = now() - year = defaultdate.year - if epoch and 'B' in epoch: - year = -year + 1 - # Default to 1 if no day is given - if day: - day = int(day) - else: - day = 1 - month = int(month) - # Could have mistaken us format for euro style date - # which uses day, month order - if month > 12 or month == 0: - match = None - continue - break - - elif format == 'lit': - # US style literal date - match = _litdateRE.search(text) - if match is not None: - litday,day,litmonth,month,year,epoch = match.groups() - break - - elif format == 'altlit': - # Alternative US style literal date - match = _altlitdateRE.search(text) - if match is not None: - litday,litmonth,day,year,epoch = match.groups() - month = '' - break - - elif format == 'eurlit': - # European style literal date - match = _eurlitdateRE.search(text) - if match is not None: - litday,day,litmonth,year,epoch = match.groups() - month = '' - break - - elif format == 'unknown': - # No date part: use defaultdate - if defaultdate is None: - defaultdate = now() - year = defaultdate.year - month = defaultdate.month - day = defaultdate.day - style = format - break - - # Check success - if match is not None: - # Remove date from text - left, right = match.span() - if 0 and _debug: - print 'parsed date:',repr(text[left:right]),\ - 'giving:',year,month,day - text = text[:left] + text[right:] - style = format - - elif not style: - # Not recognized: raise an error - raise ValueError, 'unknown date format: "%s"' % text - - # Literal date post-processing - if style in ('lit', 'altlit', 'eurlit'): - if 0 and _debug: print match.groups() - # Default to current year, January 1st - if not year: - if defaultdate is None: - defaultdate = now() - year = defaultdate.year - else: - if len(year) == 2: - # Y2K problem: - year = add_century(int(year)) - else: - year = int(year) - if epoch and 'B' in epoch: - year = -year + 1 - if litmonth: - litmonth = lower(litmonth) - try: - month = litmonthtable[litmonth] - except KeyError: - raise ValueError,\ - 'wrong month name: "%s"' % litmonth - elif month: - month = int(month) - else: - month = 1 - if day: - day = int(day) - else: - day = 1 - - #print '_parse_date:',text,day,month,year,style - return text,day,month,year,style - -def _parse_time(text, formats=_time_formats, - - int=int,float=float,replace=string.replace): - - """ Parses a time part given in text and returns a tuple - (text,hour,minute,second,offset,style) with the following - meanings: - - * text gives the original text without the time part - * hour,minute,second give the parsed time - * offset gives the time zone UTC offset - * style gives information about which parser was successful: - 'standard' - the standard parser - 'iso' - the ISO time format parser - 'unknown' - no time part was found - - formats may be set to a tuple specifying the parsers to use: - 'standard' - standard time format with ':' delimiter - 'iso' - ISO time format (superset of 'standard') - 'unknown' - default to 0:00:00, 0 zone offset - - If 'unknown' is not given in formats and the time cannot be - parsed, a ValueError is raised. - - """ - match = None - style = '' - - # Apply parsers in the order given in formats - for format in formats: - - # Standard format - if format == 'standard': - match = _timeRE.search(text) - if match is not None: - hour,minute,second,ampm,zone = match.groups() - style = 'standard' - break - - # ISO format - if format == 'iso': - match = _isotimeRE.search(text) - if match is not None: - hour,minute,second,zone = match.groups() - ampm = None - style = 'iso' - break - - # Default handling - elif format == 'unknown': - hour,minute,second,offset = 0,0,0.0,0 - style = 'unknown' - break - - if not style: - # If no default handling should be applied, raise an error - raise ValueError, 'unknown time format: "%s"' % text - - # Post-processing - if match is not None: - if zone: - # Convert to UTC offset - offset = Timezone.utc_offset(zone) - else: - offset = 0 - hour = int(hour) - if ampm: - if ampm[0] in ('p', 'P'): - # 12pm = midday - if hour < 12: - hour = hour + 12 - else: - # 12am = midnight - if hour >= 12: - hour = hour - 12 - if minute: - minute = int(minute) - else: - minute = 0 - if not second: - second = 0.0 - else: - if ',' in second: - second = replace(second, ',', '.') - second = float(second) - - # Remove time from text - left,right = match.span() - if 0 and _debug: - print 'parsed time:',repr(text[left:right]),\ - 'giving:',hour,minute,second,offset - text = text[:left] + text[right:] - - #print '_parse_time:',text,hour,minute,second,offset,style - return text,hour,minute,second,offset,style - -### - -def DateTimeFromString(text, formats=_date_formats, defaultdate=None, - time_formats=_time_formats, - - DateTime=DateTime): - - """ DateTimeFromString(text, [formats, defaultdate]) - - Returns a DateTime instance reflecting the date and time given - in text. In case a timezone is given, the returned instance - will point to the corresponding UTC time value. Otherwise, the - value is set as given in the string. - - formats may be set to a tuple of strings specifying which of - the following parsers to use and in which order to try - them. Default is to try all of them in the order given below: - - 'euro' - the European date parser - 'us' - the US date parser - 'altus' - the alternative US date parser (with '-' instead of '/') - 'iso' - the ISO date parser - 'altiso' - the alternative ISO date parser (without '-') - 'usiso' - US style ISO date parser (yyyy/mm/dd) - 'lit' - the US literal date parser - 'altlit' - the alternative US literal date parser - 'eurlit' - the Eurpean literal date parser - 'unknown' - if no date part is found, use defaultdate - - defaultdate provides the defaults to use in case no date part - is found. Most of the parsers default to the current year - January 1 if some of these date parts are missing. - - If 'unknown' is not given in formats and the date cannot - be parsed, a ValueError is raised. - - time_formats may be set to a tuple of strings specifying which - of the following parsers to use and in which order to try - them. Default is to try all of them in the order given below: - - 'standard' - standard time format HH:MM:SS (with ':' delimiter) - 'iso' - ISO time format (superset of 'standard') - 'unknown' - default to 00:00:00 in case the time format - cannot be parsed - - Defaults to 00:00:00.00 for time parts that are not included - in the textual representation. - - If 'unknown' is not given in time_formats and the time cannot - be parsed, a ValueError is raised. - - """ - origtext = text - formats = tuple(formats) - - if formats is _date_formats or \ - 'iso' in formats or \ - 'altiso' in formats: - - # First try standard order (parse time, then date) - if formats[0] not in ('iso', 'altiso'): - text,hour,minute,second,offset,timestyle = _parse_time( - origtext, - time_formats) - text,day,month,year,datestyle = _parse_date( - text, - formats + ('unknown',), - defaultdate) - if 0 and _debug: - print 'tried time/date on %s, date=%s, time=%s' % (origtext, - datestyle, - timestyle) - else: - timestyle = 'iso' - - # If this fails, try the ISO order (date, then time) - if timestyle in ('iso', 'unknown'): - text,day,month,year,datestyle = _parse_date( - origtext, - formats, - defaultdate) - text,hour,minute,second,offset,timestyle = _parse_time( - text, - time_formats) - if 0 and _debug: - print 'tried ISO on %s, date=%s, time=%s' % (origtext, - datestyle, - timestyle) - else: - # Standard order: time part, then date part - text,hour,minute,second,offset,timestyle = _parse_time( - origtext, - time_formats) - text,day,month,year,datestyle = _parse_date( - text, - formats, - defaultdate) - - if (datestyle == 'unknown' and 'unknown' not in formats) or \ - (timestyle == 'unknown' and 'unknown' not in time_formats): - raise ValueError,\ - 'Failed to parse "%s": found "%s" date, "%s" time' % \ - (origtext, datestyle, timestyle) - - try: - return DateTime.DateTime(year,month,day,hour,minute,second) - offset - except DateTime.RangeError, why: - raise DateTime.RangeError,\ - 'Failed to parse "%s": %s' % (origtext, why) - -def DateFromString(text, formats=_date_formats, defaultdate=None, - - DateTime=DateTime): - - """ DateFromString(text, [formats, defaultdate]) - - Returns a DateTime instance reflecting the date given in - text. A possibly included time part is ignored. - - formats and defaultdate work just like for - DateTimeFromString(). - - """ - _text,day,month,year,datestyle = _parse_date(text, formats, defaultdate) - - if datestyle == 'unknown' and \ - 'unknown' not in formats: - raise ValueError,\ - 'Failed to parse "%s": found "%s" date' % \ - (origtext, datestyle) - - try: - return DateTime.DateTime(year,month,day) - except DateTime.RangeError, why: - raise DateTime.RangeError,\ - 'Failed to parse "%s": %s' % (text, why) - -def validateDateTimeString(text, formats=_date_formats): - - """ validateDateTimeString(text, [formats, defaultdate]) - - Validates the given text and returns 1/0 depending on whether - text includes parseable date and time values or not. - - formats works just like for DateTimeFromString() and defines - the order of date/time parsers to apply. It defaults to the - same list of parsers as for DateTimeFromString(). - - XXX Undocumented ! - - """ - formats = list(formats) - if 'unknown' in formats: - formats.remove('unknown') - try: - DateTimeFromString(text, formats) - except (DateTime.RangeError, ValueError), why: - return 0 - return 1 - -def validateDateString(text, formats=_date_formats): - - """ validateDateString(text, [formats, defaultdate]) - - Validates the given text and returns 1/0 depending on whether - text includes a parseable date value or not. - - formats works just like for DateTimeFromString() and defines - the order of date/time parsers to apply. It defaults to the - same list of parsers as for DateTimeFromString(). - - XXX Undocumented ! - - """ - formats = list(formats) - if 'unknown' in formats: - formats.remove('unknown') - try: - DateFromString(text, formats) - except (DateTime.RangeError, ValueError), why: - return 0 - return 1 - -def TimeFromString(text, formats=_time_formats, - - DateTime=DateTime): - - """ TimeFromString(text, [formats]) - - Returns a DateTimeDelta instance reflecting the time given in - text. A possibly included date part is ignored. - - formats may be set to a tuple of strings specifying which of - the following parsers to use and in which order to try - them. Default is to try all of them in the order given below: - - 'standard' - standard time format with ':' delimiter - 'iso' - ISO time format (superset of 'standard') - 'unknown' - default to 00:00:00 in case the time format - cannot be parsed - - Defaults to 00:00:00.00 for parts that are not included in the - textual representation. - - """ - _text,hour,minute,second,offset,timestyle = _parse_time( - text, - formats) - - if timestyle == 'unknown' and \ - 'unknown' not in formats: - raise ValueError,\ - 'Failed to parse "%s": found "%s" time' % \ - (text, timestyle) - - try: - dtd = DateTime.DateTimeDelta(0.0, hour, minute, second) - except DateTime.RangeError, why: - raise DateTime.RangeError,\ - 'Failed to parse "%s": %s' % (text, why) - else: - # XXX What to do with offset ? - return dtd - -# -# XXX Still missing: validateTimeString(), validateDateTimeDeltaString() -# and validateTimeDeltaString() -# - -def DateTimeDeltaFromString(text, - - float=float,DateTime=DateTime): - - """ DateTimeDeltaFromString(text) - - Returns a DateTimeDelta instance reflecting the delta given in - text. Defaults to 0:00:00:00.00 for parts that are not - included in the textual representation or cannot be parsed. - - """ - match = _isodelta1RE.search(text) - if match is not None: - sign, days, hours, minutes, seconds = match.groups() - else: - match = _litdelta2RE.search(text) - if match is not None: - sign, days, hours, minutes, seconds = match.groups() - else: - match = _isodelta2RE.search(text) - if match is not None: - sign, hours, minutes, seconds = match.groups() - days = None - else: - match = _isodelta3RE.search(text) - if match is not None: - sign, hours, minutes = match.groups() - days = None - seconds = None - else: - match = _litdeltaRE.search(text) - if match is not None: - sign, days, hours, minutes, seconds = match.groups() - - else: - # Not matched: - return DateTime.DateTimeDelta(0.0) - - # Conversions - if days: - days = float(days) - else: - days = 0.0 - if hours: - hours = float(hours) - else: - hours = 0.0 - if minutes: - minutes = float(minutes) - else: - minutes = 0.0 - if seconds: - seconds = float(seconds) - else: - seconds = 0.0 - if sign != '-': - sign = 1 - else: - sign = -1 - - try: - dtd = DateTime.DateTimeDelta(days,hours,minutes,seconds) - except DateTime.RangeError, why: - raise DateTime.RangeError,\ - 'Failed to parse "%s": %s' % (text, why) - else: - if sign < 0: - return -dtd - else: - return dtd - -# Aliases -TimeDeltaFromString = DateTimeDeltaFromString - -### - -def _parse_reldate(text, - - int=int,float=float): - - match = _relisodateRE.search(text) - if match is not None: - groups = match.groups() - if 0 and _debug: print groups - year,years,month,months,day,days = groups - if year: - year = int(year) - if years: - years = float(years) - else: - years = 0 - if month: - month = int(month) - if months: - months = float(months) - else: - months = 0 - if day: - day = int(day) - if days: - days = float(days) - else: - days = 0 - return year,years,month,months,day,days - else: - return None,0,None,0,None,0 - -def _parse_reltime(text, - - int=int,float=float): - - match = _relisotimeRE.search(text) - if match is not None: - groups = match.groups() - if 0 and _debug: print groups - hour,hours,minute,minutes,second,seconds = groups - if hour: - hour = int(hour) - if hours: - hours = float(hours) - else: - hours = 0 - if minute: - minute = int(minute) - if minutes: - minutes = float(minutes) - else: - minutes = 0 - if second: - second = int(second) - if seconds: - seconds = float(seconds) - else: - seconds = 0 - return hour,hours,minute,minutes,second,seconds - else: - return None,0,None,0,None,0 - -def RelativeDateTimeFromString(text, - - RelativeDateTime=DateTime.RelativeDateTime): - - """ RelativeDateTimeFromString(text) - - Returns a RelativeDateTime instance reflecting the relative - date and time given in text. - - Defaults to wildcards for parts or values which are not - included in the textual representation or cannot be parsed. - - The format used in text must adhere to the following syntax: - - [YYYY-MM-DD] [HH:MM[:SS]] - - with the usual meanings. Values which should not be altered - may be replaced with '*', '%', '?' or any combination of - letters, e.g. 'YYYY'. Relative settings must be enclosed in - parenthesis if given and should include a sign, e.g. '(+0001)' - for the year part. All other settings are interpreted as - absolute values. - - Date and time parts are both optional as a whole. Seconds in - the time part are optional too. Everything else (including the - hyphens and colons) is mandatory. - - """ - year,years,month,months,day,days = _parse_reldate(text) - hour,hours,minute,minutes,second,seconds = _parse_reltime(text) - return RelativeDateTime(year=year,years=years, - month=month,months=months, - day=day,days=days, - hour=hour,hours=hours, - minute=minute,minutes=minutes, - second=second,seconds=seconds) - -def RelativeDateFromString(text, - - RelativeDateTime=DateTime.RelativeDateTime): - - """ RelativeDateFromString(text) - - Same as RelativeDateTimeFromString(text) except that only the - date part of text is taken into account. - - """ - year,years,month,months,day,days = _parse_reldate(text) - return RelativeDateTime(year=year,years=years, - month=month,months=months, - day=day,days=days) - -def RelativeTimeFromString(text, - - RelativeDateTime=DateTime.RelativeDateTime): - - """ RelativeTimeFromString(text) - - Same as RelativeDateTimeFromString(text) except that only the - time part of text is taken into account. - - """ - hour,hours,minute,minutes,second,seconds = _parse_reltime(text) - return RelativeDateTime(hour=hour,hours=hours, - minute=minute,minutes=minutes, - second=second,seconds=seconds) - -### Tests - -def _test(): - - import sys - - t = DateTime.now() - - print 'Testing DateTime Parser...' - - l = [ - - # Literal formats - ('Sun Nov 6 08:49:37 1994', '1994-11-06 08:49:37.00'), - ('sun nov 6 08:49:37 1994', '1994-11-06 08:49:37.00'), - ('sUN NOV 6 08:49:37 1994', '1994-11-06 08:49:37.00'), - ('Sunday, 06-Nov-94 08:49:37 GMT', '1994-11-06 08:49:37.00'), - ('Sun, 06 Nov 1994 08:49:37 GMT', '1994-11-06 08:49:37.00'), - ('06-Nov-94 08:49:37', '1994-11-06 08:49:37.00'), - ('06-Nov-94', '1994-11-06 00:00:00.00'), - ('06-NOV-94', '1994-11-06 00:00:00.00'), - ('November 19 08:49:37', '%s-11-19 08:49:37.00' % t.year), - ('Nov. 9', '%s-11-09 00:00:00.00' % t.year), - ('Sonntag, der 6. November 1994, 08:49:37 GMT', '1994-11-06 08:49:37.00'), - ('6. November 2001, 08:49:37', '2001-11-06 08:49:37.00'), - ('sep 6', '%s-09-06 00:00:00.00' % t.year), - ('sep 6 2000', '2000-09-06 00:00:00.00'), - ('September 29', '%s-09-29 00:00:00.00' % t.year), - ('Sep. 29', '%s-09-29 00:00:00.00' % t.year), - ('6 sep', '%s-09-06 00:00:00.00' % t.year), - ('29 September', '%s-09-29 00:00:00.00' % t.year), - ('29 Sep.', '%s-09-29 00:00:00.00' % t.year), - ('sep 6 2001', '2001-09-06 00:00:00.00'), - ('Sep 6, 2001', '2001-09-06 00:00:00.00'), - ('September 6, 2001', '2001-09-06 00:00:00.00'), - ('sep 6 01', '2001-09-06 00:00:00.00'), - ('Sep 6, 01', '2001-09-06 00:00:00.00'), - ('September 6, 01', '2001-09-06 00:00:00.00'), - ('30 Apr 2006 20:19:00', '2006-04-30 20:19:00.00'), - - # ISO formats - ('1994-11-06 08:49:37', '1994-11-06 08:49:37.00'), - ('010203', '2001-02-03 00:00:00.00'), - ('2001-02-03 00:00:00.00', '2001-02-03 00:00:00.00'), - ('2001-02 00:00:00.00', '2001-02-01 00:00:00.00'), - ('2001-02-03', '2001-02-03 00:00:00.00'), - ('2001-02', '2001-02-01 00:00:00.00'), - ('20000824/2300', '2000-08-24 23:00:00.00'), - ('20000824/0102', '2000-08-24 01:02:00.00'), - ('20000824', '2000-08-24 00:00:00.00'), - ('20000824/020301', '2000-08-24 02:03:01.00'), - ('20000824 020301', '2000-08-24 02:03:01.00'), - ('-20000824 020301', '-2000-08-24 02:03:01.00'), - ('20000824T020301', '2000-08-24 02:03:01.00'), - ('20000824 020301', '2000-08-24 02:03:01.00'), - ('2000-08-24 02:03:01.00', '2000-08-24 02:03:01.00'), - ('T020311', '%s 02:03:11.00' % t.date), - ('2003-12-9', '2003-12-09 00:00:00.00'), - ('03-12-9', '2003-12-09 00:00:00.00'), - ('003-12-9', '0003-12-09 00:00:00.00'), - ('0003-12-9', '0003-12-09 00:00:00.00'), - ('2003-1-9', '2003-01-09 00:00:00.00'), - ('03-1-9', '2003-01-09 00:00:00.00'), - ('003-1-9', '0003-01-09 00:00:00.00'), - ('0003-1-9', '0003-01-09 00:00:00.00'), - - # US formats - ('06/11/94 08:49:37', '1994-06-11 08:49:37.00'), - ('11/06/94 08:49:37', '1994-11-06 08:49:37.00'), - ('9/23/2001', '2001-09-23 00:00:00.00'), - ('9-23-2001', '2001-09-23 00:00:00.00'), - ('9/6', '%s-09-06 00:00:00.00' % t.year), - ('09/6', '%s-09-06 00:00:00.00' % t.year), - ('9/06', '%s-09-06 00:00:00.00' % t.year), - ('09/06', '%s-09-06 00:00:00.00' % t.year), - ('9/6/2001', '2001-09-06 00:00:00.00'), - ('09/6/2001', '2001-09-06 00:00:00.00'), - ('9/06/2001', '2001-09-06 00:00:00.00'), - ('09/06/2001', '2001-09-06 00:00:00.00'), - ('9-6-2001', '2001-09-06 00:00:00.00'), - ('09-6-2001', '2001-09-06 00:00:00.00'), - ('9-06-2001', '2001-09-06 00:00:00.00'), - ('09-06-2001', '2001-09-06 00:00:00.00'), - ('2002/05/28 13:10:56.1147 GMT+2', '2002-05-28 13:10:56.11'), - ('1970/01/01', '1970-01-01 00:00:00.00'), - ('20021025 12:00 PM', '2002-10-25 12:00:00.00'), - ('20021025 12:30 PM', '2002-10-25 12:30:00.00'), - ('20021025 12:00 AM', '2002-10-25 00:00:00.00'), - ('20021025 12:30 AM', '2002-10-25 00:30:00.00'), - ('20021025 1:00 PM', '2002-10-25 13:00:00.00'), - ('20021025 2:00 AM', '2002-10-25 02:00:00.00'), - ('Thursday, February 06, 2003 12:40 PM', '2003-02-06 12:40:00.00'), - ('Mon, 18 Sep 2006 23:03:00', '2006-09-18 23:03:00.00'), - - # European formats - ('6.11.2001, 08:49:37', '2001-11-06 08:49:37.00'), - ('06.11.2001, 08:49:37', '2001-11-06 08:49:37.00'), - ('06.11. 08:49:37', '%s-11-06 08:49:37.00' % t.year), - #('21/12/2002', '2002-12-21 00:00:00.00'), - #('21/08/2002', '2002-08-21 00:00:00.00'), - #('21-08-2002', '2002-08-21 00:00:00.00'), - #('13/01/03', '2003-01-13 00:00:00.00'), - #('13/1/03', '2003-01-13 00:00:00.00'), - #('13/1/3', '2003-01-13 00:00:00.00'), - #('13/01/3', '2003-01-13 00:00:00.00'), - - # Time only formats - ('01:03', '%s 01:03:00.00' % t.date), - ('01:03:11', '%s 01:03:11.00' % t.date), - ('01:03:11.50', '%s 01:03:11.50' % t.date), - ('01:03:11.50 AM', '%s 01:03:11.50' % t.date), - ('01:03:11.50 PM', '%s 13:03:11.50' % t.date), - ('01:03:11.50 a.m.', '%s 01:03:11.50' % t.date), - ('01:03:11.50 p.m.', '%s 13:03:11.50' % t.date), - - # Invalid formats - ('6..2001, 08:49:37', '%s 08:49:37.00' % t.date), - ('9//2001', 'ignore'), - ('06--94 08:49:37', 'ignore'), - ('20000824020301', 'ignore'), - ('20-03 00:00:00.00', 'ignore'), - ('9/2001', 'ignore'), - ('9-6', 'ignore'), - ('09-6', 'ignore'), - ('9-06', 'ignore'), - ('09-06', 'ignore'), - ('20000824/23', 'ignore'), - ('November 1994 08:49:37', 'ignore'), - ('Nov. 94', 'ignore'), - ('Mon, 18 Sep 2006 23:03:00 +1234567890', 'ignore'), - - ] - - # Add Unicode versions - try: - unicode - except NameError: - pass - else: - k = [] - for text, result in l: - k.append((unicode(text), result)) - l.extend(k) - - for text, reference in l: - try: - value = DateTimeFromString(text) - except: - if reference is None: - continue - else: - value = str(sys.exc_info()[1]) - valid_datetime = validateDateTimeString(text) - valid_date = validateDateString(text) - if str(value) != reference and \ - not reference == 'ignore': - print 'Failed to parse "%s"' % text - print ' expected: %s' % (reference or '') - print ' parsed: %s' % value - elif _debug: - print 'Parsed "%s" successfully' % text - if _debug: - if not valid_datetime: - print ' "%s" failed date/time validation' % text - if not valid_date: - print ' "%s" failed date validation' % text - - et = DateTime.now() - print 'done. (after %f seconds)' % ((et-t).seconds) - - ### - - print 'Testing DateTimeDelta Parser...' - - t = DateTime.now() - l = [ - - # Literal formats - ('Sun Nov 6 08:49:37 1994', '08:49:37.00'), - ('1 day, 8 hours, 49 minutes, 37 seconds', '1:08:49:37.00'), - ('10 days, 8 hours, 49 minutes, 37 seconds', '10:08:49:37.00'), - ('8 hours, 49 minutes, 37 seconds', '08:49:37.00'), - ('49 minutes, 37 seconds', '00:49:37.00'), - ('37 seconds', '00:00:37.00'), - ('37.5 seconds', '00:00:37.50'), - ('8 hours later', '08:00:00.00'), - ('2 days', '2:00:00:00.00'), - ('2 days 23h', '2:23:00:00.00'), - ('2 days 23:57', '2:23:57:00.00'), - ('2 days 23:57:13', '2:23:57:13.00'), - ('', '00:00:00.00'), - - # ISO formats - ('1994-11-06 08:49:37', '08:49:37.00'), - ('10:08:49:37', '10:08:49:37.00'), - ('08:49:37', '08:49:37.00'), - ('08:49', '08:49:00.00'), - ('-10:08:49:37', '-10:08:49:37.00'), - ('-08:49:37', '-08:49:37.00'), - ('-08:49', '-08:49:00.00'), - ('- 10:08:49:37', '-10:08:49:37.00'), - ('- 08:49:37', '-08:49:37.00'), - ('- 08:49', '-08:49:00.00'), - ('10:08:49:37.5', '10:08:49:37.50'), - ('08:49:37.5', '08:49:37.50'), - ('10:8:49:37', '10:08:49:37.00'), - ('8:9:37', '08:09:37.00'), - ('8:9', '08:09:00.00'), - ('8', '00:00:00.00'), - - # Invalid formats - #('', None), - #('8', None), - - ] - - for text, reference in l: - try: - value = DateTimeDeltaFromString(text) - except: - if reference is None: - continue - else: - value = str(sys.exc_info()[1]) - if str(value) != reference and \ - not reference == 'ignore': - print 'Failed to parse "%s"' % text - print ' expected: %s' % (reference or '') - print ' parsed: %s' % value - elif _debug: - print 'Parsed "%s" successfully' % text - - et = DateTime.now() - print 'done. (after %f seconds)' % ((et-t).seconds) - - ### - - print 'Testing Time Parser...' - - t = DateTime.now() - l = [ - - # Standard formats - ('08:49:37 AM', '08:49:37.00'), - ('08:49:37 PM', '20:49:37.00'), - ('12:00:00 AM', '00:00:00.00'), - ('12:00:00 PM', '12:00:00.00'), - ('8:09:37', '08:09:37.00'), - ('8:09', '08:09:00.00'), - - # ISO formats - ('08:49:37', '08:49:37.00'), - ('08:49', '08:49:00.00'), - ('08:49:37.5', '08:49:37.50'), - ('08:49:37,5', '08:49:37.50'), - ('08:09', '08:09:00.00'), - - # Invalid formats - ('', None), - ('8:9:37', 'XXX Should give an exception'), - ('08:9:37', 'XXX Should give an exception'), - ('8:9', None), - ('8', None), - - ] - - for text, reference in l: - try: - value = TimeFromString(text, formats=('standard', 'iso')) - except: - if reference is None: - continue - else: - value = str(sys.exc_info()[1]) - if str(value) != reference and \ - not reference == 'ignore': - print 'Failed to parse "%s"' % text - print ' expected: %s' % (reference or '') - print ' parsed: %s' % value - elif _debug: - print 'Parsed "%s" successfully' % text - - et = DateTime.now() - print 'done. (after %f seconds)' % ((et-t).seconds) - -if __name__ == '__main__': - _test() diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/Timezone.py --- a/embedded/mx/DateTime/Timezone.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -# -*- coding: latin-1 -*- - -""" Timezone information. - - XXX This module still has prototype status and is undocumented. - - XXX Double check the offsets given in the zonetable below. - - XXX Add TZ environment variable parsing functions. The REs are already - there. - - Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. - -""" -import DateTime -import re,string - -### REs - -# time zone parsing -isozone = ('(?P[+-]\d\d:?(?:\d\d)?|Z)') -zone = ('(?P[A-Z]+|[+-]\d\d?:?(?:\d\d)?)') -zoneoffset = ('(?:' - '(?P[+-])?' - '(?P\d\d?)' - ':?' - '(?P\d\d)?' - '(?P\d+)?' - ')' - ) - -# TZ environment variable parsing -dstswitchtime = ('(?P\d\d?):?' - '(?P\d\d)?:?' - '(?P\d\d)?') -dstswitch = ('(?:' - '(?P\d+)|' - '(?:J(?P\d+))|' - '(?:M(?P\d+).(?P\d+).(?P\d+))' - ')' - '(?:/' + dstswitchtime + ')?' - ) - -# XXX Doesn't work since re doesn't like multiple occurrences of -# group names. -#tz = ('(?::(?P.+))|' -# '(?P[A-Z]+)' + zoneoffset + -# '(?:' -# '(?P[A-Z]+)' + zoneoffset + '?'+ -# '(?:[;,]' + dstswitch + '[;,]' + dstswitch + ')' -# ')?' -# ) - -# Compiled RE objects -isozoneRE = re.compile(zone) -zoneRE = re.compile(zone) -zoneoffsetRE = re.compile(zoneoffset) -#tzRE= re.compile(tz) - -### Time zone offset table -# -# The offset given here represent the difference between UTC and the -# given time zone. -# -# Additions and corrections are always welcome :-) -# -# Note that some zone names are ambiguous, e.g. IST can refer to Irish -# Summer Time, Indian Standard Time, Israel Standard Time. We've -# usualy chosen meaning with the most wide-spread use. -# -zonetable = { - # Timezone abbreviations - # Std Summer - - # Standards - 'UT':0, - 'UTC':0, - 'GMT':0, - - # A few common timezone abbreviations - 'CET':1, 'CEST':2, 'CETDST':2, # Central European - 'MET':1, 'MEST':2, 'METDST':2, # Mean European - 'MEZ':1, 'MESZ':2, # Mitteleuropäische Zeit - 'EET':2, 'EEST':3, 'EETDST':3, # Eastern Europe - 'WET':0, 'WEST':1, 'WETDST':1, # Western Europe - 'MSK':3, 'MSD':4, # Moscow - 'IST':5.5, # India - 'JST':9, # Japan - 'KST':9, # Korea - 'HKT':8, # Hong Kong - - # US time zones - 'AST':-4, 'ADT':-3, # Atlantic - 'EST':-5, 'EDT':-4, # Eastern - 'CST':-6, 'CDT':-5, # Central - 'MST':-7, 'MDT':-6, # Midwestern - 'PST':-8, 'PDT':-7, # Pacific - - # Australian time zones - 'CAST':9.5, 'CADT':10.5, # Central - 'EAST':10, 'EADT':11, # Eastern - 'WAST':8, 'WADT':9, # Western - 'SAST':9.5, 'SADT':10.5, # Southern - - # US military time zones - 'Z': 0, - 'A': 1, - 'B': 2, - 'C': 3, - 'D': 4, - 'E': 5, - 'F': 6, - 'G': 7, - 'H': 8, - 'I': 9, - 'K': 10, - 'L': 11, - 'M': 12, - 'N':-1, - 'O':-2, - 'P':-3, - 'Q':-4, - 'R':-5, - 'S':-6, - 'T':-7, - 'U':-8, - 'V':-9, - 'W':-10, - 'X':-11, - 'Y':-12 - } - -def utc_offset(zone, - - atoi=string.atoi,zoneoffset=zoneoffsetRE, - zonetable=zonetable,zerooffset=DateTime.DateTimeDelta(0), - oneMinute=DateTime.oneMinute,upper=string.upper): - - """ utc_offset(zonestring) - - Return the UTC time zone offset as DateTimeDelta instance. - - zone must be string and can either be given as +-HH:MM, - +-HHMM, +-HH numeric offset or as time zone - abbreviation. Daylight saving time must be encoded into the - zone offset. - - Timezone abbreviations are treated case-insensitive. - - """ - if not zone: - return zerooffset - uzone = upper(zone) - if zonetable.has_key(uzone): - return zonetable[uzone]*DateTime.oneHour - offset = zoneoffset.match(zone) - if not offset: - raise ValueError,'wrong format or unknown time zone: "%s"' % zone - zonesign,hours,minutes,extra = offset.groups() - if extra: - raise ValueError,'illegal time zone offset: "%s"' % zone - offset = int(hours or 0) * 60 + int(minutes or 0) - if zonesign == '-': - offset = -offset - return offset*oneMinute - diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/__init__.py --- a/embedded/mx/DateTime/__init__.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -""" mxDateTime - Date and time handling routines and types - - Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com - Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. -""" -from DateTime import * -from DateTime import __version__ - -## mock strptime implementation -from datetime import datetime - -def strptime(datestr, formatstr, datetime=datetime): - """mocked strptime implementation""" - date = datetime.strptime(datestr, formatstr) - return DateTime(date.year, date.month, date.day, - date.hour, date.minute, date.second) - -# don't expose datetime directly -del datetime diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/DateTime/mxDateTime_python.py --- a/embedded/mx/DateTime/mxDateTime_python.py Tue Apr 28 15:38:06 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,614 +0,0 @@ -""" - Python implementation courtesy of Drew Csillag (StarMedia Network, Inc.) - - This version has been somewhat modified by MAL. It is still fairly - rough though and not necessarily high performance... - - XXX Still needs testing and checkup !!! - - WARNING: Using this file is only recommended if you really must - use it for some reason. It is not being actively maintained ! - -""" - -__version__ = '1.2.0 [Python]' - -import time,types,exceptions,math - -### Errors - -class Error(exceptions.StandardError): - pass - -class RangeError(Error): - pass - -### Constants (internal use only) - -month_offset=( - (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365), - (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366), - ) - -days_in_month=( - (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), - (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), - ) - -### Helpers - -def _IS_LEAPYEAR(d): - return ((d.year % 4 == 0) - and ( - (d.year % 100 != 0) - or (d.year % 400 == 0) - ) - ) - -def _YEAROFFSET(d): - return ( - (d.year - 1) * 365 - + (d.year - 1) / 4 - - (d.year - 1) / 100 - + (d.year - 1) / 400 - ) - -class _EmptyClass: - pass - -def createEmptyObject(Class, - _EmptyClass=_EmptyClass): - - o = _EmptyClass() - o.__class__ = Class - return o - -### DateTime class - -class DateTime: - - def __init__(self, year, month=1, day=1, hour=0, minute=0, second=0.0): - - second=1.0 * second - if month <= 0: - raise RangeError, "year out of range (>0)" - - #calculate absolute date - leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0)) - - #Negative values indicate days relative to the years end - if month < 0: - month = month + 13 - - if not (month >= 1 and month <= 12): - raise RangeError, "month out of range (1-12)" - - #Negative values indicate days relative to the months end - if (day < 0): - day = day + days_in_month[leap][month - 1] + 1; - - if not (day >= 1 and day <= days_in_month[leap][month - 1]): - raise RangeError, "day out of range" - - year = year - 1 - yearoffset = year * 365 + year / 4 - year / 100 + year / 400 - year = year + 1 - absdate = day + month_offset[leap][month - 1] + yearoffset; - - self.absdate = absdate - self.year = year - self.month = month - self.day = day - self.day_of_week = (absdate - 1) % 7 - self.day_of_year = absdate - yearoffset - self.days_in_month = days_in_month[leap][month - 1] - comdate = absdate - 693594 - - if not (hour >=0 and hour <= 23): - raise RangeError, "hour out of range (0-23)" - if not (minute >= 0 and minute <= 59): - raise RangeError, "minute out of range (0-59)" - if not (second >= 0.0 and - (second < 60.0 or - (hour == 23 and minute == 59 and second < 61.0))): - raise RangeError, "second out of range (0.0 - <60.0; <61.0 for 23:59)" - - self.abstime = (hour * 3600 + minute * 60) + second - self.hour = hour - self.minute = minute - self.second = second - self.dst = -1 - self.tz = "???" - self.is_leapyear = leap - self.yearoffset = yearoffset - self.iso_week = (self.year, self.day, self.day_of_week) - - if comdate < 0.0: - comdate = comdate - self.abstime / 86400.0 - else: - comdate = comdate + self.abstime / 86400.0 - - self.comdate = comdate - - def COMDate(self): - return self.comdate - - def __str__(self): - return "%04d-%02d-%02d %02d:%02d:%05.2f" % ( - self.year, self.month, self.day, self.hour, self.minute, - self.second) - - def __getattr__(self, attr): - if attr == 'mjd': - return (self - mjd0).days - elif attr == 'jdn': - return (self - jdn0).days - elif attr == 'tjd': - return (self - jdn0).days % 10000 - elif attr == 'tjd_myriad': - return int((self - jdn0).days) / 10000 + 240 - elif attr == 'absdays': - return self.absdate - 1 + self.abstime / 86400.0 - else: - try: - return self.__dict__[attr] - except: - raise AttributeError, attr - - def __mul__(self, other): - raise TypeError, "bad operand type(s) for *" - - def __div__(self, other): - raise TypeError, "bad operand type(s) for /" - - def strftime(self, format_string="%c"): - "localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)" - # The map prevents a deprecation warning on Python 2.5.1 (Mac) - # DeprecationWarning: integer argument expected, got float - items = [int(item) for item in self.tuple()] - return time.strftime(format_string, items) - - # Alias - Format = strftime - - def tuple(self): - return (self.year, self.month, self.day, self.hour, self.minute, - self.second, self.day_of_week, self.day_of_year, -1) - #return time.localtime(self.ticks()) - - def absvalues(self): - return self.absdate, self.abstime - - def __float__(self): - return self.ticks() - - def __int__(self): - return int(self.ticks) - - def ticks(self, offset=0.0, dst=-1): - tticks=time.mktime(self.year, self.month, self.day, self.hour, - self.minute, self.second, self.day_of_week, 0, dst) - if tticks == -1: - raise OverflowError, "cannot convert value to a time value" - ticks = (1.0*tticks) + (self.abstime - int(self.abstime)) - offset - return ticks - - def gmticks(self, offset=0.0): - from mx.DateTime import tz_offset - return (self-tz_offset(self)).ticks() - - def gmtoffset(self): - gmtime = DateTime(*time.gmtime()[:6]) - return - (now() - gmtime) - - def __repr__(self): - return ""% ( - self.year, self.month, self.day, self.hour, self.minute, - self.second, id(self)) - - def __cmp__(self, other, - cmp=cmp): - - if isinstance(other,DateTime): - cmpdate = cmp(self.absdate,other.absdate) - if cmpdate == 0: - return cmp(self.abstime,other.abstime) - else: - return cmpdate - elif type(other) == types.NoneType: - return -1 - elif type(other) == types.StringType: - return -1 - elif type(other) in (types.FloatType, types.LongType, types.IntType): - return 1 - return -1 - - def __hash__(self): - return hash(self.tuple()) - - def __add__(self, other): - abstime=self.abstime - absdate=self.absdate - - didadd=0 - - if type(other) == types.InstanceType: - if other.__class__ == DateTimeDelta: - abstime = abstime + other.seconds - didadd=1 - elif other.__class__ == DateTime: - raise TypeError, "DateTime + DateTime is not supported" - else: - return other.__class__.__radd__(other, self) - - elif type(other) == types.IntType or type(other) == types.FloatType: - abstime = abstime + other * 86400.0 - didadd=1 - - if not didadd: - raise TypeError, "cannot add these two types" - - if abstime >= 86400.0: - days = abstime / 86400.0 - absdate = absdate + days - abstime = abstime - (86400.0 * int(days)) - #print "absdate, abstime = ", absdate, abstime - elif abstime < 0.0: - days = int(((-abstime - 1) / 86400.0)) + 1 - #days = int(-abstime / 86400.0) - absdate = absdate - days - abstime = abstime + 86400.0 * int(days) - - if absdate < 1: - raise RangeError, "underflow while adding" - - return DateTimeFromAbsDateTime(absdate, abstime) - - def __radd__(self, other): - return DateTime.__add__(other, self) - - def __sub__(self, other): - abstime=self.abstime - absdate=self.absdate - - didsub=0 - if type(other) == types.InstanceType: - if other.__class__ == DateTimeDelta: - abstime = abstime - other.seconds - didsub = 1 - elif other.__class__ == DateTime: - absdate = absdate - other.absdate - abstime = abstime - other.abstime - return DateTimeDelta(absdate,0.0,0.0,abstime) - else: - return other.__rsub__(self) - - elif type(other) == types.IntType or type(other) == types.FloatType: - abstime = abstime - other * 86400.0; - didsub=1 - - if not didsub: - raise TypeError, "cannot subtract these two types" - - if abstime >= 86400.0: - days = abstime / 86400.0 - absdate = absdate + days - abstime = abstime - (86400.0 * days) - #print "absdate, abstime = ", absdate, abstime - elif abstime < 0.0: - #print "abstime < 0" - days = int( ((-abstime - 1) / 86400.0) + 1) - #days = -abstime / 86400.0 - absdate = absdate - int(days) - abstime = (1.0*abstime) + (86400.0 * days) - #print "absdate, abstime", absdate, abstime - if absdate < 1: - raise RangeError, "underflow while adding" - - return DateTimeFromAbsDateTime(absdate, abstime) - -# Constants -mjd0 = DateTime(1858, 11, 17) -jdn0 = DateTime(-4713, 1, 1, 12, 0, 0.0) - -# Other DateTime constructors - -def DateTimeFromCOMDate(comdate): - - absdate = int(comdate) - abstime = (comdate - float(absdate)) * 86400.0 - if abstime < 0.0: - abstime = -abstime - absdate = absdate + 693594; - dt = DateTimeFromAbsDateTime(absdate, abstime) - dt.comdate = comdate - return dt - -def DateTimeFromAbsDateTime(absdate, abstime): - - # Create the object without calling its default constructor - dt = createEmptyObject(DateTime) - - # Init. the object - abstime=1.0 * abstime - if abstime < 0 and abstime > -0.001: abstime = 0.0 - if not (absdate > 0): - raise RangeError, "absdate out of range (>0)" - if not (abstime >= 0.0 and abstime <= 86400.0): - raise RangeError, "abstime out of range (0.0 - 86400.0) <%s>" % abstime - - dt.absdate=absdate - dt.abstime=abstime - - #calculate com date - comdate = 1.0 * (dt.absdate - 693594) - if comdate < 0.0: - comdate = comdate - dt.abstime / 86400.0 - else: - comdate = comdate + dt.abstime / 86400.0 - dt.comdate = comdate - - #calculate the date - #print "absdate=", absdate - year = int((1.0 * absdate) / 365.2425) - - #newApproximation: - while 1: - #print "year=", year - yearoffset = year * 365 + year / 4 - year / 100 + year / 400 - #print "yearoffset=", yearoffset - #print "absdate=", absdate - if yearoffset >= absdate: - year = year - 1 - #print "year = ", year - continue #goto newApproximation - - year = year + 1 - leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0)) - dayoffset = absdate - yearoffset - #print "dayoffset=", dayoffset - if dayoffset > 365 and leap == 0: - #print "dayoffset=", dayoffset - continue #goto newApproximation - - monthoffset = month_offset[leap] - for month in range(1, 13): - if monthoffset[month] >= dayoffset: - break - dt.year = year - dt.month = month - dt.day = dayoffset - month_offset[leap][month-1] - dt.day_of_week = (dt.absdate - 1) % 7 - dt.day_of_year = dayoffset - break - - #calculate the time - inttime = int(abstime) - hour = inttime / 3600 - minute = (inttime % 3600) / 60 - second = abstime - 1.0 * (hour*3600 + minute*60) - dt.hour = hour; - dt.minute = minute; - dt.second = second; - dt.days_in_month = days_in_month[leap][month - 1] - dt.dst = -1 - dt.tz = "???" - dt.is_leapyear = leap - dt.yearoffset = yearoffset - return dt - -def now( - time=time.time,float=float,localtime=time.localtime, - round=round,int=int,DateTime=DateTime,floor=math.floor): - ticks = time() - Y,M,D,h,m,s = localtime(ticks)[:6] - s = s + (ticks - floor(ticks)) - return DateTime(Y,M,D,h,m,s) - -def utc( - time=time.time,float=float,gmtime=time.gmtime, - round=round,int=int,DateTime=DateTime,floor=math.floor): - - ticks = time() - Y,M,D,h,m,s = gmtime(ticks)[:6] - s = s + (ticks - floor(ticks)) - return DateTime(Y,M,D,h,m,s) - -# Aliases -Date = Timestamp = DateTime - -# XXX Calendars are not supported: -def notSupported(*args,**kws): - raise Error,'calendars are not supported by the Python version of mxDateTime' -JulianDateTime = notSupported - -### DateTimeDelta class - -class DateTimeDelta: - - def __init__(self, days=0, hours=0, minutes=0, seconds=0): - - seconds = seconds + (days * 86400.0 + hours * 3600.0 + minutes * 60.0) - self.seconds = seconds - if seconds < 0.0: - seconds = -seconds - day = long(seconds / 86400.0) - seconds = seconds - (86400.0 * day) - wholeseconds = int(seconds) - hour = wholeseconds / 3600 - minute = (wholeseconds % 3600) / 60 - second = seconds - (hour * 3600.0 + minute * 60.0) - self.day = day - self.hour = hour - self.minute = minute - self.second = second - seconds=self.seconds - self.minutes = seconds / 60.0 - self.hours = seconds / 3600.0 - self.days = seconds / 86400.0 - - def __str__(self): - if self.day != 0: - if self.seconds >= 0.0: - r="%s:%02d:%02d:%05.2f" % ( - self.day, self.hour, self.minute, self.second) - else: - r="-%s:%02d:%02d:%05.2f" % ( - self.day, self.hour, self.minute, self.second) - else: - if self.seconds >= 0.0: - r="%02d:%02d:%05.2f" % (self.hour, self.minute, self.second) - else: - r="-%02d:%02d:%05.2f" % (self.hour, self.minute, self.second) - return r - - def absvalues(self): - days=self.seconds / 86400 - seconds=self.seconds - (days * 86400.0) - return days, seconds - - def tuple(self): - return (self.day, self.hour, self.minute, self.second) - - def strftime(self, format_string): - raise NotImplementedError - - def __int__(self): - return int(self.seconds) - - def __float__(self): - return self.seconds - - def __cmp__(self, other, accuracy=0.0): - if (type(other) == types.InstanceType - and other.__class__ == DateTimeDelta): - - diff=self.seconds - other.seconds - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - elif type(other) == types.FloatType: - diff=self.seconds - other - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - elif type(other) == types.IntType: - diff=self.seconds - other - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - return 0 - - def __getattr__(self, attr): - seconds=self.__dict__['seconds'] - if attr in ('hour', 'minute', 'second', 'day'): - if seconds >= 0.0: - return self.__dict__[attr] - else: - return -self.__dict__[attr] - else: - try: - return self.__dict__[attr] - except: - raise AttributeError, attr - - def __div__(self, other): - if type(other) in (types.IntType, types.FloatType): - return DateTimeDelta(0.0,0.0,0.0,self.seconds / other) - elif (type(other) == types.InstanceType - and isinstance(other,DateTimeDelta)): - return DateTimeDelta(0.0,0.0,0.0,self.seconds / other.seconds) - raise TypeError, "bad operand types for /" - - def __mul__(self, other): - if type(other) == types.IntType or type(other) == types.FloatType: - return DateTimeDelta(0.0,0.0,0.0,self.seconds * other) - else: - #print "type", type(other) - raise TypeError, "cannot multiply these two types" - - def __rmul__(self, other): - return self.__mul__(other) - - def __neg__(self): - return DateTimeDelta(0.0,0.0,0.0,-self.seconds) - - def __repr__(self): - if self.day != 0: - if self.seconds >= 0.0: - strval="%s:%02d:%02d:%05.2f" % (self.day, self.hour, - self.minute, self.second) - else: - strval="-%s:%02d:%02d:%05.2f" % (self.day, self.hour, - self.minute, self.second) - else: - if self.seconds >= 0.0: - strval="%02d:%02d:%05.2f" % (self.hour, self.minute, - self.second) - else: - strval="-%02d:%02d:%05.2f" % (self.hour, self.minute, - self.second) - return "" % (strval, id(self)) - - def __abs__(self): - if self.seconds < 0: - return -self - return self - - def __nonzero__(self): - return self.seconds != 0.0 - - def __add__(self, other): - if type(other) == types.InstanceType: - if isinstance(other,DateTime): - return other + self - elif isinstance(other,DateTimeDelta): - return DateTimeDelta(0.0,0.0,0.0,self.seconds + other.seconds) - - # What about __radd__ ? - -# Other DateTimeDelta constructors - -def TimeDelta(hour=0.0, minute=0.0, second=0.0): - return DateTimeDelta(0.0, hours, minutes, seconds) - -Time=TimeDelta - -def DateTimeDeltaFromSeconds(seconds): - return DateTimeDelta(0.0,0.0,0.0,seconds) - -def DateTimeDeltaFromDays(days): - return DateTimeDelta(days) - -### Types - -DateTimeType = DateTime -DateTimeDeltaType = DateTimeDelta - -### Functions - -def cmp(a,b,acc): - - if isinstance(a,DateTime) and isinstance(b,DateTime): - diff = a.absdays - b.absdays - if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc): - return 0 - elif diff < 0: - return 1 - else: - return -1 - - elif isinstance(a,DateTimeDelta) and isinstance(b,DateTimeDelta): - diff = a.days - b.days - if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc): - return 0 - elif diff < 0: - return 1 - else: - return -1 - - else: - raise TypeError,"objects must be DateTime[Delta] instances" diff -r e4c99610e1f7 -r b38e888ee7e3 embedded/mx/__init__.py