1.1 --- a/imip_manager.py Mon Feb 02 18:46:59 2015 +0100
1.2 +++ b/imip_manager.py Mon Feb 02 19:43:14 2015 +0100
1.3 @@ -24,7 +24,7 @@
1.4
1.5 LIBRARY_PATH = "/var/lib/imip-agent"
1.6
1.7 -from datetime import datetime
1.8 +from datetime import date, datetime, timedelta
1.9 import babel.dates
1.10 import cgi, os, sys
1.11
1.12 @@ -295,7 +295,14 @@
1.13 return self._format_datetime(babel.dates.format_time, dt, format)
1.14
1.15 def format_datetime(self, dt, format):
1.16 - return self._format_datetime(babel.dates.format_datetime, dt, format)
1.17 + return self._format_datetime(
1.18 + isinstance(dt, datetime) and babel.dates.format_datetime or babel.dates.format_date,
1.19 + dt, format)
1.20 +
1.21 + def format_end_datetime(self, dt, format):
1.22 + if isinstance(dt, date):
1.23 + dt = dt - timedelta(1)
1.24 + return self.format_datetime(dt, format)
1.25
1.26 def _format_datetime(self, fn, dt, format):
1.27 return fn(dt, format=format, locale=self.get_user_locale())
1.28 @@ -543,7 +550,9 @@
1.29 if name in ["DTSTART", "DTEND"]:
1.30 value, attr = obj.get_item(name)
1.31 tzid = attr.get("TZID", tzid)
1.32 - value = self.format_datetime(to_timezone(get_datetime(value), tzid), "full")
1.33 + value = (
1.34 + name == "DTSTART" and self.format_datetime or self.format_end_datetime
1.35 + )(to_timezone(get_datetime(value), tzid), "full")
1.36 page.th(label, class_="objectheading")
1.37 page.td(value)
1.38 page.tr.close()
2.1 --- a/imiptools/dates.py Mon Feb 02 18:46:59 2015 +0100
2.2 +++ b/imiptools/dates.py Mon Feb 02 19:43:14 2015 +0100
2.3 @@ -51,7 +51,7 @@
2.4 return to_tz(dt, tz)
2.5
2.6 def to_tz(dt, tz):
2.7 - if tz is not None:
2.8 + if tz is not None and isinstance(dt, datetime):
2.9 if not dt.tzinfo:
2.10 return tz.localize(dt)
2.11 else:
2.12 @@ -80,29 +80,33 @@
2.13 if not attr or attr.get("VALUE") in (None, "DATE-TIME"):
2.14 m = match_datetime_icalendar(value)
2.15 if m:
2.16 - dt = datetime(
2.17 - int(m.group("year")), int(m.group("month")), int(m.group("day")),
2.18 - int(m.group("hour")), int(m.group("minute")), int(m.group("second"))
2.19 - )
2.20 + year, month, day, hour, minute, second = map(m.group, [
2.21 + "year", "month", "day", "hour", "minute", "second"
2.22 + ])
2.23
2.24 - # Impose the indicated timezone.
2.25 - # NOTE: This needs an ambiguity policy for DST changes.
2.26 + if hour and minute and second:
2.27 + dt = datetime(
2.28 + int(year), int(month), int(day), int(hour), int(minute), int(second)
2.29 + )
2.30
2.31 - return to_timezone(dt, m.group("utc") and "UTC" or attr and attr.get("TZID") or None)
2.32 + # Impose the indicated timezone.
2.33 + # NOTE: This needs an ambiguity policy for DST changes.
2.34 +
2.35 + return to_timezone(dt, m.group("utc") and "UTC" or attr and attr.get("TZID") or None)
2.36
2.37 if not attr or attr.get("VALUE") == "DATE":
2.38 m = match_date_icalendar(value)
2.39 if m:
2.40 - return date(
2.41 - int(m.group("year")), int(m.group("month")), int(m.group("day"))
2.42 - )
2.43 + year, month, day = map(m.group, ["year", "month", "day"])
2.44 + return date(int(year), int(month), int(day))
2.45 +
2.46 return None
2.47
2.48 -def get_start_of_day(dt):
2.49 - return datetime(dt.year, dt.month, dt.day, 0, 0, tzinfo=dt.tzinfo)
2.50 +def get_start_of_day(dt, tzid=None):
2.51 + return datetime(dt.year, dt.month, dt.day, 0, 0, tzinfo=(tzid and timezone(tzid) or dt.tzinfo))
2.52
2.53 -def get_end_of_day(dt):
2.54 - return get_start_of_day(dt + timedelta(1))
2.55 +def get_end_of_day(dt, tzid=None):
2.56 + return get_start_of_day(dt + timedelta(1), tzid)
2.57
2.58 def ends_on_same_day(dt, end):
2.59 return (
3.1 --- a/imiptools/period.py Mon Feb 02 18:46:59 2015 +0100
3.2 +++ b/imiptools/period.py Mon Feb 02 19:43:14 2015 +0100
3.3 @@ -20,6 +20,7 @@
3.4 """
3.5
3.6 from bisect import bisect_left, insort_left
3.7 +from datetime import datetime
3.8 from imiptools.dates import get_datetime, get_start_of_day, to_timezone
3.9
3.10 # Time management.
3.11 @@ -124,9 +125,16 @@
3.12 start, end = t[:2]
3.13
3.14 # NOTE: This only really works if the datetimes are UTC already.
3.15 + # NOTE: Since the periods should originate from the free/busy data,
3.16 + # NOTE: and since that data should employ UTC times, this should not be
3.17 + # NOTE: an immediate problem.
3.18
3.19 - start = to_timezone(get_datetime(start), tzid)
3.20 - end = to_timezone(get_datetime(end), tzid)
3.21 + start = get_datetime(start)
3.22 + end = get_datetime(end)
3.23 +
3.24 + start = isinstance(start, datetime) and to_timezone(start, tzid) or get_start_of_day(start, tzid)
3.25 + end = isinstance(end, datetime) and to_timezone(end, tzid) or get_start_of_day(end, tzid)
3.26 +
3.27 l.append((start, end) + tuple(t[2:]))
3.28
3.29 return l