# HG changeset patch # User Paul Boddie # Date 1297018123 -3600 # Node ID 0cedf2a634d931c61c2c1fb38aba548c9f271c9f # Parent d572e4225280516166c0bce97062e29a6abfb11d Changed getDateTime to return Date instances where no time information has been provided. Changed the meaning of DateTime instances with no time information (where the has_time method returns a false value) to indicate the start of a day. Changed the comparison of DateTime instances so that those without time information behave like those with a time of 00:00:00. Made the getCoverageScale function convert dates to timeless datetimes. Altered timespan comparisons so that timeless datetimes can be considered "earlier" than dates if they are otherwise found to be equal. Introduced some configuration to the padded method of DateTime instances. diff -r d572e4225280 -r 0cedf2a634d9 EventAggregatorSupport.py --- a/EventAggregatorSupport.py Sun Feb 06 02:49:57 2011 +0100 +++ b/EventAggregatorSupport.py Sun Feb 06 19:48:43 2011 +0100 @@ -979,12 +979,13 @@ if isinstance(start, DateTime): times.add(start) + else: + times.add(start.as_datetime(None, None, None, None)) if isinstance(end, DateTime): - if end.has_time(): - times.add(end) - else: - times.add(end.as_date().next_day()) + times.add(end) + else: + times.add(end.as_date().next_day()) times = list(times) times.sort(cmp_dates_as_day_start) @@ -1087,6 +1088,12 @@ units.append(current) return units + def ambiguous(self): + + "Only times can be ambiguous." + + return 0 + class Month(Temporal): "A simple year-month representation." @@ -1288,19 +1295,29 @@ compares their raw time data. """ - this = self.as_datetime_or_date() - - if isinstance(this, DateTime) and isinstance(other, DateTime): - other = other.as_datetime_or_date() + this = self + + if this.has_time(): if isinstance(other, DateTime): - this_utc = this.to_utc() - other_utc = other.to_utc() - if this_utc is not None and other_utc is not None: - return cmp(this_utc.as_tuple(), other_utc.as_tuple()) + if other.has_time(): + this_utc = this.to_utc() + other_utc = other.to_utc() + if this_utc is not None and other_utc is not None: + return cmp(this_utc.as_tuple(), other_utc.as_tuple()) + else: + other = other.padded() + else: + this = this.padded() return Date.__cmp__(this, other) def has_time(self): + + """ + Return whether this object has any time information. Objects without + time information can refer to the very start of a day. + """ + return self.data[3] is not None and self.data[4] is not None def time(self): @@ -1315,11 +1332,21 @@ def set_time_zone(self, value): self.data[6] = value - def padded(self): - - "Return a datetime with missing fields defined as being zero." - - data = map(lambda x: x or 0, self.data[:6]) + self.data[6:] + def padded(self, empty_value=0): + + """ + Return a datetime with missing fields defined as being the given + 'empty_value' or 0 if not specified. + """ + + data = [] + for x in self.data[:6]: + if x is None: + data.append(empty_value) + else: + data.append(x) + + data += self.data[6:] return DateTime(data) def to_utc(self): @@ -1520,7 +1547,10 @@ comparisons. """ - if isinstance(a, DateTime) and a.has_time() and isinstance(b, DateTime) and b.has_time(): + # Datetimes without times can be equal to dates and be considered as + # occurring before those dates. + + if isinstance(a, DateTime) and (isinstance(b, DateTime) or not a.has_time()): return a <= b else: return a < b @@ -1554,13 +1584,10 @@ else: return 0 - # Points in time are not considered to represent an upper bound on a - # non-inclusive timespan. - else: if self.end is not None and self.is_before(self.end, other): return -1 - elif self.start is not None and self.start > other: + elif self.start is not None and self.is_before(other, self.start): return 1 else: return 0 @@ -1644,7 +1671,11 @@ def getDateTime(s): - "Parse the string 's', extracting and returning a datetime object." + """ + Parse the string 's', extracting and returning a datetime object where time + information has been given or a date object where time information is + absent. + """ m = datetime_regexp.search(s) if m: @@ -1652,7 +1683,7 @@ # Convert date and time data to integer or None. - return DateTime(map(int_or_none, groups[:6]) + [m.group("zone")]) + return DateTime(map(int_or_none, groups[:6]) + [m.group("zone")]).as_datetime_or_date() else: return None