--- a/embedded/mx/DateTime/DateTime.py Tue May 05 17:18:49 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