1.1 --- a/DateSupport.py Sun Mar 25 21:19:17 2012 +0200
1.2 +++ b/DateSupport.py Mon Mar 26 00:14:22 2012 +0200
1.3 @@ -29,7 +29,7 @@
1.4 month_regexp_str = ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})'
1.5 date_regexp_str = ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})-(?P<day>[0-9]{2})'
1.6 time_regexp_str = ur'(?P<hour>[0-2][0-9]):(?P<minute>[0-5][0-9])(?::(?P<second>[0-6][0-9]))?'
1.7 -timezone_offset_str = ur'(?P<offset>(UTC)?(?:(?P<sign>[-+])(?P<hours>[0-9]{2})(?::?(?P<minutes>[0-9]{2}))?))'
1.8 +timezone_offset_str = ur'(?P<offset>(UTC)?(?:(?P<sign>[-+])?(?P<hours>[0-9]{2})(?::?(?P<minutes>[0-9]{2}))?))'
1.9 timezone_olson_str = ur'(?P<olson>[a-zA-Z]+(?:/[-_a-zA-Z]+){1,2})'
1.10 timezone_utc_str = ur'UTC'
1.11 timezone_regexp_str = ur'(?P<zone>' + timezone_offset_str + '|' + timezone_olson_str + '|' + timezone_utc_str + ')'
1.12 @@ -56,6 +56,12 @@
1.13
1.14 # Utility functions.
1.15
1.16 +def sign(x):
1.17 + if x < 0:
1.18 + return -1
1.19 + else:
1.20 + return 1
1.21 +
1.22 def int_or_none(x):
1.23 if x is None:
1.24 return x
1.25 @@ -164,10 +170,12 @@
1.26 else:
1.27 data = self.as_tuple()
1.28 other_data = other.as_tuple()
1.29 + direction = self < other and 1 or -1
1.30 +
1.31 if len(data) < len(other_data):
1.32 - return len(self.until(other))
1.33 + return (len(self.until(other)) - 1) * direction
1.34 else:
1.35 - return len(other.until(self))
1.36 + return (len(other.until(self)) - 1) * -direction
1.37
1.38 def _until(self, start, end, nextfn, prevfn):
1.39
1.40 @@ -442,6 +450,25 @@
1.41
1.42 return Date.__cmp__(this, other)
1.43
1.44 + def __sub__(self, other):
1.45 +
1.46 + """
1.47 + Return the difference between this object and the 'other' object at the
1.48 + highest common accuracy of both objects.
1.49 + """
1.50 +
1.51 + if not isinstance(other, Temporal):
1.52 + return NotImplemented
1.53 + elif not other.has_time():
1.54 + return self.as_date() - other
1.55 + else:
1.56 + utc = self.to_utc()
1.57 + other = other.to_utc()
1.58 + days = utc.as_date() - other.as_date()
1.59 + h1, m1, s1 = utc.as_tuple()[3:6]
1.60 + h2, m2, s2 = other.as_tuple()[3:6]
1.61 + return days * 24 * 3600 + (h1 - h2) * 3600 + (m1 - m2) * 60 + s1 - s2
1.62 +
1.63 def has_time(self):
1.64
1.65 """
1.66 @@ -546,12 +573,12 @@
1.67 match = timezone_offset_regexp.match(zone)
1.68 if match:
1.69 if match.group("sign") == "-":
1.70 - sign = -1
1.71 + offset_sign = -1
1.72 else:
1.73 - sign = 1
1.74 + offset_sign = 1
1.75
1.76 - hours = int(match.group("hours")) * sign
1.77 - minutes = int(match.group("minutes") or 0) * sign
1.78 + hours = int(match.group("hours")) * offset_sign
1.79 + minutes = int(match.group("minutes") or 0) * offset_sign
1.80 return hours, minutes
1.81
1.82 # Attempt to handle Olson time zone identifiers.
1.83 @@ -559,9 +586,9 @@
1.84 dt = self.as_olson_datetime()
1.85 if dt:
1.86 seconds = dt.utcoffset().seconds + dt.utcoffset().days * 24 * 3600
1.87 - hours = seconds / 3600
1.88 - minutes = (seconds % 3600) / 60
1.89 - return hours, minutes
1.90 + hours = abs(seconds) / 3600
1.91 + minutes = (abs(seconds) % 3600) / 60
1.92 + return sign(seconds) * hours, sign(seconds) * minutes
1.93
1.94 # Otherwise return None.
1.95
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tests/test_dates.py Mon Mar 26 00:14:22 2012 +0200
2.3 @@ -0,0 +1,60 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +from DateSupport import *
2.7 +
2.8 +d1 = DateTime((2012, 3, 25, 20, 45, 30, "Europe/Oslo"))
2.9 +d2 = DateTime((2012, 3, 25, 21, 05, 25, "Europe/Oslo"))
2.10 +ts1 = Timespan(d1, d1)
2.11 +ts2 = Timespan(d1, d2)
2.12 +
2.13 +# expected result operands
2.14 +print "%r : %r <- %r < %r" % (d1 < d2, d1 < d2, d1, d2)
2.15 +print "%r : %r <- %r == %r" % (not d1 == d2, d1 == d2, d1, d2)
2.16 +print "%r : %r <- %r < %r" % (ts1 < ts2, ts1 < ts2, ts1, ts2)
2.17 +print "%r : %r <- %r == %r" % (not ts1 == ts2, ts1 == ts2, ts1, ts2)
2.18 +
2.19 +d2_offset = d2.utc_offset()
2.20 +
2.21 +# expected result operands
2.22 +print "%r : %r <- %r.utc_offset()" % (d2_offset == (2, 0), d2_offset, d2)
2.23 +
2.24 +d3 = DateTime((2012, 3, 25, 21, 05, 25, "America/Montreal"))
2.25 +d4 = DateTime((2012, 3, 25, 21, 05, 25, "America/Anchorage"))
2.26 +d5 = DateTime((2012, 3, 25, 21, 05, 25, "America/St_Johns"))
2.27 +d6 = DateTime((2012, 3, 25, 21, 05, 25, "America/Vancouver"))
2.28 +d7 = DateTime((2012, 3, 25, 21, 05, 25, "-05:45"))
2.29 +d8 = DateTime((2012, 3, 25, 21, 05, 25, "05:45"))
2.30 +
2.31 +# expected result operands
2.32 +print "%r : %r <- %r < %r" % (d2 < d3, d2 < d3, d2, d3)
2.33 +print "%r : %r <- %r < %r" % (d3 < d4, d3 < d4, d3, d4)
2.34 +print "%r : %r <- %r > %r" % (d4 > d5, d4 > d5, d4, d5)
2.35 +print "%r : %r <- %r > %r" % (not d5 > d6, d5 > d6, d5, d6)
2.36 +print "%r : %r <- %r > %r" % (d6 > d7, d6 > d7, d6, d7)
2.37 +print "%r : %r <- %r > %r" % (d7 > d8, d7 > d8, d7, d8)
2.38 +
2.39 +d3_offset = d3.utc_offset()
2.40 +d4_offset = d4.utc_offset()
2.41 +d5_offset = d5.utc_offset()
2.42 +d6_offset = d6.utc_offset()
2.43 +d7_offset = d7.utc_offset()
2.44 +d8_offset = d8.utc_offset()
2.45 +
2.46 +# expected result operands
2.47 +print "%r : %r <- %r.utc_offset()" % (d3_offset == (-4, 0), d3_offset, d3)
2.48 +print "%r : %r <- %r.utc_offset()" % (d4_offset == (-8, 0), d4_offset, d4)
2.49 +print "%r : %r <- %r.utc_offset()" % (d5_offset == (-2, -30), d5_offset, d5)
2.50 +print "%r : %r <- %r.utc_offset()" % (d6_offset == (-7, 0), d6_offset, d6)
2.51 +print "%r : %r <- %r.utc_offset()" % (d7_offset == (-5, -45), d7_offset, d7)
2.52 +print "%r : %r <- %r.utc_offset()" % (d8_offset == (5, 45), d8_offset, d8)
2.53 +
2.54 +# expected result operands
2.55 +print "%r : %r <- %r - %r" % (d2 - d2 == 0, d2 - d2, d2, d2)
2.56 +print "%r : %r <- %r - %r" % (d3 - d2 == 6 * 3600, d3 - d2, d3, d2)
2.57 +print "%r : %r <- %r - %r" % (d4 - d2 == 10 * 3600, d4 - d2, d4, d2)
2.58 +print "%r : %r <- %r - %r" % (d5 - d2 == 4.5 * 3600, d5 - d2, d5, d2)
2.59 +print "%r : %r <- %r - %r" % (d6 - d2 == 9 * 3600, d6 - d2, d6, d2)
2.60 +print "%r : %r <- %r - %r" % (d7 - d2 == 7.75 * 3600, d7 - d2, d7, d2)
2.61 +print "%r : %r <- %r - %r" % (d8 - d2 == -3.75 * 3600, d8 - d2, d8, d2)
2.62 +
2.63 +# vim: tabstop=4 expandtab shiftwidth=4