Esempio n. 1
0
class vDatetime(object):
    """Render and generates icalendar datetime format.

    vDatetime is timezone aware and uses the pytz library, an implementation of
    the Olson database in Python. When a vDatetime object is created from an
    ical string, you can pass a valid pytz timezone identifier. When a
    vDatetime object is created from a python datetime object, it uses the
    tzinfo component, if present. Otherwise an timezone-naive object is
    created. Be aware that there are certain limitations with timezone naive
    DATE-TIME components in the icalendar standard.
    """
    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        dt = self.dt
        tzid = tzid_from_dt(dt)

        s = "%04d%02d%02dT%02d%02d%02d" % (dt.year, dt.month, dt.day, dt.hour,
                                           dt.minute, dt.second)
        if tzid == 'UTC':
            s += "Z"
        elif tzid:
            self.params.update({'TZID': tzid})
        return s.encode('utf-8')

    @staticmethod
    def from_ical(ical, timezone=None):
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                if timezone in WINDOWS_TO_OLSON:
                    tzinfo = pytz.timezone(WINDOWS_TO_OLSON.get(timezone))
                else:
                    tzinfo = _timezone_cache.get(timezone, None)

        try:
            timetuple = (
                int(ical[:4]),  # year
                int(ical[4:6]),  # month
                int(ical[6:8]),  # day
                int(ical[9:11]),  # hour
                int(ical[11:13]),  # minute
                int(ical[13:15]),  # second
            )
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return pytz.utc.localize(datetime(*timetuple))
            else:
                raise ValueError(ical)
        except:
            raise ValueError('Wrong datetime format: %s' % ical)
Esempio n. 2
0
class vDDDTypes(object):
    """A combined Datetime, Date or Duration parser/generator. Their format
    cannot be confused, and often values can be of either types.
    So this is practical.
    """
    def __init__(self, dt):
        if not isinstance(dt, (datetime, date, timedelta, time)):
            raise ValueError('You must use datetime, date, timedelta or time')
        if isinstance(dt, datetime):
            self.params = Parameters({'value': 'DATE-TIME'})
        elif isinstance(dt, date):
            self.params = Parameters({'value': 'DATE'})
        elif isinstance(dt, time):
            self.params = Parameters({'value': 'TIME'})

        if (isinstance(dt, datetime) or isinstance(dt, time))\
                and getattr(dt, 'tzinfo', False):
            tzinfo = dt.tzinfo
            if tzinfo is not pytz.utc and\
               (tzutc is None or not isinstance(tzinfo, tzutc)):
                # set the timezone as a parameter to the property
                tzid = tzid_from_dt(dt)
                if tzid:
                    self.params.update({'TZID': tzid})
        self.dt = dt

    def to_ical(self):
        dt = self.dt
        if isinstance(dt, datetime):
            return vDatetime(dt).to_ical()
        elif isinstance(dt, date):
            return vDate(dt).to_ical()
        elif isinstance(dt, timedelta):
            return vDuration(dt).to_ical()
        elif isinstance(dt, time):
            return vTime(dt).to_ical()
        else:
            raise ValueError('Unknown date type')

    @classmethod
    def from_ical(cls, ical, timezone=None):
        if isinstance(ical, cls):
            return ical.dt
        u = ical.upper()
        if u.startswith(('P', '-P', '+P')):
            return vDuration.from_ical(ical)

        if len(ical) in (15, 16):
            return vDatetime.from_ical(ical, timezone=timezone)
        elif len(ical) == 8:
            return vDate.from_ical(ical)
        elif len(ical) in (6, 7):
            return vTime.from_ical(ical)
        else:
            raise ValueError(
                "Expected datetime, date, or time, got: '%s'" % ical
            )
Esempio n. 3
0
class vDDDTypes(object):
    """A combined Datetime, Date or Duration parser/generator. Their format
    cannot be confused, and often values can be of either types.
    So this is practical.
    """
    def __init__(self, dt):
        if not isinstance(dt, (datetime, date, timedelta, time)):
            raise ValueError('You must use datetime, date, timedelta or time')
        if isinstance(dt, datetime):
            self.params = Parameters({'value': 'DATE-TIME'})
        elif isinstance(dt, date):
            self.params = Parameters({'value': 'DATE'})
        elif isinstance(dt, time):
            self.params = Parameters({'value': 'TIME'})

        if (isinstance(dt, datetime) or isinstance(dt, time))\
                and getattr(dt, 'tzinfo', False):
            tzinfo = dt.tzinfo
            if tzinfo is not pytz.utc and\
               (tzutc is None or not isinstance(tzinfo, tzutc)):
                # set the timezone as a parameter to the property
                tzid = tzid_from_dt(dt)
                if tzid:
                    self.params.update({'TZID': tzid})
        self.dt = dt

    def to_ical(self):
        dt = self.dt
        if isinstance(dt, datetime):
            return vDatetime(dt).to_ical()
        elif isinstance(dt, date):
            return vDate(dt).to_ical()
        elif isinstance(dt, timedelta):
            return vDuration(dt).to_ical()
        elif isinstance(dt, time):
            return vTime(dt).to_ical()
        else:
            raise ValueError('Unknown date type')

    @classmethod
    def from_ical(cls, ical, timezone=None):
        if isinstance(ical, cls):
            return ical.dt
        u = ical.upper()
        if u.startswith(('P', '-P', '+P')):
            return vDuration.from_ical(ical)

        if len(ical) in (15, 16):
            return vDatetime.from_ical(ical, timezone=timezone)
        elif len(ical) == 8:
            return vDate.from_ical(ical)
        elif len(ical) in (6, 7):
            return vTime.from_ical(ical)
        else:
            raise ValueError("Expected datetime, date, or time, got: '%s'" %
                             ical)
Esempio n. 4
0
class vDatetime(object):
    """Render and generates icalendar datetime format.

    vDatetime is timezone aware and uses the pytz library, an implementation of
    the Olson database in Python. When a vDatetime object is created from an
    ical string, you can pass a valid pytz timezone identifier. When a
    vDatetime object is created from a python datetime object, it uses the
    tzinfo component, if present. Otherwise an timezone-naive object is
    created. Be aware that there are certain limitations with timezone naive
    DATE-TIME components in the icalendar standard.
    """
    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        dt = self.dt
        tzid = tzid_from_dt(dt)

        s = "%04d%02d%02dT%02d%02d%02d" % (
            dt.year,
            dt.month,
            dt.day,
            dt.hour,
            dt.minute,
            dt.second
        )
        if tzid == 'UTC':
            s += "Z"
        elif tzid:
            self.params.update({'TZID': tzid})
        return s.encode('utf-8')

    @staticmethod
    def from_ical(ical, timezone=None):
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                tzinfo = _timezone_cache.get(timezone, None)

        try:
            timetuple = (
                int(ical[:4]),  # year
                int(ical[4:6]),  # month
                int(ical[6:8]),  # day
                int(ical[9:11]),  # hour
                int(ical[11:13]),  # minute
                int(ical[13:15]),  # second
            )
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return pytz.utc.localize(datetime(*timetuple))
            else:
                raise ValueError(ical)
        except:
            raise ValueError('Wrong datetime format: %s' % ical)
Esempio n. 5
0
class vDatetime:
    """ Render and generates icalendar datetime format.

    vDatetime is timezone aware and uses the pytz library, an implementation of
    the Olson database in Python. When a vDatetime object is created from an
    ical string, the string must be a valid pytz timezone identifier. When and
    vDatetime object is created from a python datetime object, it uses the
    tzinfo component, if present. Otherwise an timezone-naive object is
    created. Be aware that there are certain limitations with timezone naive
    DATE-TIME components in the icalendar standard.

    >>> d = datetime(2001, 1,1, 12, 30, 0)

    >>> dt = vDatetime(d)
    >>> dt.to_ical()
    '20010101T123000'

    >>> vDatetime.from_ical('20000101T120000')
    datetime.datetime(2000, 1, 1, 12, 0)

    >>> dutc = datetime(2001, 1,1, 12, 30, 0, tzinfo=pytz.utc)
    >>> vDatetime(dutc).to_ical()
    '20010101T123000Z'

    >>> vDatetime.from_ical('20010101T000000')
    datetime.datetime(2001, 1, 1, 0, 0)

    >>> vDatetime.from_ical('20010101T000000A')
    Traceback (most recent call last):
      ...
    ValueError: Wrong datetime format: 20010101T000000A

    >>> utc = vDatetime.from_ical('20010101T000000Z')
    >>> vDatetime(utc).to_ical()
    '20010101T000000Z'

    1 minute before transition to DST
    >>> dat = vDatetime.from_ical('20120311T015959', 'America/Denver')
    >>> dat.strftime('%Y%m%d%H%M%S %z')
    '20120311015959 -0700'

    After transition to DST
    >>> dat = vDatetime.from_ical('20120311T030000', 'America/Denver')
    >>> dat.strftime('%Y%m%d%H%M%S %z')
    '20120311030000 -0600'

    >>> dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna')
    >>> vDatetime(dat).to_ical()
    '20101010T000000'
    """

    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        dt = self.dt
        tzid = dt.tzinfo and dt.tzinfo.zone or None
        if tzid == 'UTC':
            return dt.strftime("%Y%m%dT%H%M%SZ")
        elif tzid:
            self.params.update({'TZID': tzid})
        return dt.strftime("%Y%m%dT%H%M%S")

    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                pass

        try:
            timetuple = map(int, ((
                ical[:4],       # year
                ical[4:6],      # month
                ical[6:8],      # day
                ical[9:11],     # hour
                ical[11:13],    # minute
                ical[13:15],    # second
                )))
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=pytz.utc, *timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical
    from_ical = staticmethod(from_ical)
Esempio n. 6
0
class vDatetime:
    """ Render and generates icalendar datetime format.

    vDatetime is timezone aware and uses the pytz library, an implementation of
    the Olson database in Python. When a vDatetime object is created from an
    ical string, the string must be a valid pytz timezone identifier. When and
    vDatetime object is created from a python datetime object, it uses the
    tzinfo component, if present. Otherwise an timezone-naive object is
    created. Be aware that there are certain limitations with timezone naive
    DATE-TIME components in the icalendar standard.

    >>> from icalendar.tools import utctz

    >>> d = datetime(2001, 1,1, 12, 30, 0)

    >>> dt = vDatetime(d)
    >>> dt.to_ical()
    '20010101T123000'

    >>> vDatetime.from_ical('20000101T120000')
    datetime.datetime(2000, 1, 1, 12, 0)

    >>> dutc = datetime(2001, 1,1, 12, 30, 0, tzinfo=utctz())
    >>> vDatetime(dutc).to_ical()
    '20010101T123000Z'

    >>> vDatetime.from_ical('20010101T000000')
    datetime.datetime(2001, 1, 1, 0, 0)

    >>> vDatetime.from_ical('20010101T000000A')
    Traceback (most recent call last):
      ...
    ValueError: Wrong datetime format: 20010101T000000A

    >>> utc = vDatetime.from_ical('20010101T000000Z')
    >>> vDatetime(utc).to_ical()
    '20010101T000000Z'

    >>> dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna')
    >>> vDatetime(dat).to_ical()
    '20101010T000000'
    """

    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        dt = self.dt
        tzid = dt.tzinfo and dt.tzinfo.zone or None
        if tzid == 'UTC':
            return dt.strftime("%Y%m%dT%H%M%SZ")
        elif tzid:
            self.params.update({'TZID': tzid})
#            return "TZID=%s;%s" % (timezone, self.dt.strftime("%Y%m%dT%H%M%S")) The timezone should not be printed with the date, but rather in the containing component.
        return dt.strftime("%Y%m%dT%H%M%S")

    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        # TODO: ical string should better contain also the TZID property.

        if timezone:
            timezone = normalized_timezone(timezone)

        try:
            timetuple = map(int, ((
                ical[:4],       # year
                ical[4:6],      # month
                ical[6:8],      # day
                ical[9:11],     # hour
                ical[11:13],    # minute
                ical[13:15],    # second
                )))
            if timezone:
                return datetime(tzinfo=timezone, *timetuple)
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=utctz(), *timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical
    from_ical = staticmethod(from_ical)
Esempio n. 7
0
class vDDDTypes:
    """A combined Datetime, Date or Duration parser/generator. Their format
    cannot be confused, and often values can be of either types.
    So this is practical.

    >>> d = vDDDTypes.from_ical('20010101T123000')
    >>> type(d)
    <type 'datetime.datetime'>

    >>> repr(vDDDTypes.from_ical('20010101T123000Z'))[:65]
    'datetime.datetime(2001, 1, 1, 12, 30, tzinfo=<UTC>)'

    >>> d = vDDDTypes.from_ical('20010101')
    >>> type(d)
    <type 'datetime.date'>

    >>> vDDDTypes.from_ical('P31D')
    datetime.timedelta(31)

    >>> vDDDTypes.from_ical('-P31D')
    datetime.timedelta(-31)

    Bad input
    >>> vDDDTypes(42)
    Traceback (most recent call last):
        ...
    ValueError: You must use datetime, date, timedelta or time
    """

    def __init__(self, dt):
        "Returns vDate from"
        if type(dt) not in (datetime, date, timedelta, time):
            raise ValueError ('You must use datetime, date, timedelta or time')
        if isinstance(dt, datetime):
            self.params = Parameters(dict(value='DATE-TIME'))
        elif isinstance(dt, date):
            self.params = Parameters(dict(value='DATE'))
        elif isinstance(dt, time):
            self.params = Parameters(dict(value='TIME'))

        if (isinstance(dt, datetime) or isinstance(dt, time))\
            and getattr(dt, 'tzinfo', False):
            tzinfo = dt.tzinfo
            if tzinfo is not pytz.utc and not isinstance(tzinfo, tzutc):
                # set the timezone as a parameter to the property
                tzid = tzid_from_dt(dt)
                if tzid:
                    self.params.update({'TZID': tzid})
        self.dt = dt

    def to_ical(self):
        dt = self.dt
        if isinstance(dt, datetime):
            return vDatetime(dt).to_ical()
        elif isinstance(dt, date):
            return vDate(dt).to_ical()
        elif isinstance(dt, timedelta):
            return vDuration(dt).to_ical()
        elif isinstance(dt, time):
            return vTime(dt).to_ical()
        else:
            raise ValueError('Unknown date type')

    @staticmethod
    def from_ical(ical, timezone=None):
        "Parses the data format from ical text format"
        if isinstance(ical, vDDDTypes):
            return ical.dt
        u = ical.upper()
        if u.startswith('-P') or u.startswith('P'):
            return vDuration.from_ical(ical)
        try:
            return vDatetime.from_ical(ical, timezone=timezone)
        except ValueError:
            try:
                return vDate.from_ical(ical)
            except ValueError:
                return vTime.from_ical(ical)
Esempio n. 8
0
class vDatetime:
    """Render and generates icalendar datetime format.

    vDatetime is timezone aware and uses the pytz library, an implementation of
    the Olson database in Python. When a vDatetime object is created from an
    ical string, the string must be a valid pytz timezone identifier. When and
    vDatetime object is created from a python datetime object, it uses the
    tzinfo component, if present. Otherwise an timezone-naive object is
    created. Be aware that there are certain limitations with timezone naive
    DATE-TIME components in the icalendar standard.

    >>> d = datetime(2001, 1,1, 12, 30, 0)

    >>> dt = vDatetime(d)
    >>> dt.to_ical()
    '20010101T123000'

    >>> vDatetime.from_ical('20000101T120000')
    datetime.datetime(2000, 1, 1, 12, 0)

    >>> dutc = datetime(2001, 1,1, 12, 30, 0, tzinfo=pytz.utc)
    >>> vDatetime(dutc).to_ical()
    '20010101T123000Z'

    >>> vDatetime.from_ical('20010101T000000')
    datetime.datetime(2001, 1, 1, 0, 0)

    >>> vDatetime.from_ical('20010101T000000A')
    Traceback (most recent call last):
      ...
    ValueError: Wrong datetime format: 20010101T000000A

    >>> utc = vDatetime.from_ical('20010101T000000Z')
    >>> vDatetime(utc).to_ical()
    '20010101T000000Z'

    1 minute before transition to DST
    >>> dat = vDatetime.from_ical('20120311T015959', 'America/Denver')
    >>> dat.strftime('%Y%m%d%H%M%S %z')
    '20120311015959 -0700'

    After transition to DST
    >>> dat = vDatetime.from_ical('20120311T030000', 'America/Denver')
    >>> dat.strftime('%Y%m%d%H%M%S %z')
    '20120311030000 -0600'

    >>> dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna')
    >>> vDatetime(dat).to_ical()
    '20101010T000000'
    """
    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        dt = self.dt
        tzid = dt.tzinfo and dt.tzinfo.zone or None
        if tzid == 'UTC':
            return dt.strftime("%Y%m%dT%H%M%SZ")
        elif tzid:
            self.params.update({'TZID': tzid})
        return dt.strftime("%Y%m%dT%H%M%S")

    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                pass

        try:
            timetuple = map(
                int,
                ((
                    ical[:4],  # year
                    ical[4:6],  # month
                    ical[6:8],  # day
                    ical[9:11],  # hour
                    ical[11:13],  # minute
                    ical[13:15],  # second
                )))
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=pytz.utc, *timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical

    from_ical = staticmethod(from_ical)
Esempio n. 9
0
class vDatetime:
    """ Render and generates iCalendar datetime format.

    Important: if tzinfo is defined it renders itself as "date with utc time"
    Meaning that it has a 'Z' appended, and is in absolute time.

    >>> d = datetime(2001, 1,1, 12, 30, 0)

    >>> dt = vDatetime(d)
    >>> dt.to_ical()
    '20010101T123000'

    >>> vDatetime.from_ical('20000101T120000')
    datetime.datetime(2000, 1, 1, 12, 0)

    >>> dutc = datetime(2001, 1,1, 12, 30, 0, tzinfo=UTC)
    >>> vDatetime(dutc).to_ical()
    '20010101T123000Z'

    >>> vDatetime.from_ical('20010101T000000')
    datetime.datetime(2001, 1, 1, 0, 0)

    >>> vDatetime.from_ical('20010101T000000A')
    Traceback (most recent call last):
      ...
    ValueError: Wrong datetime format: 20010101T000000A

    >>> utc = vDatetime.from_ical('20010101T000000Z')
    >>> vDatetime(utc).to_ical()
    '20010101T000000Z'

    >>> dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna')
    >>> vDatetime(dat).to_ical()
    'TZID=CET;20101010T000000'
    """

    def __init__(self, dt):
        self.dt = dt
        self.params = Parameters()

    def to_ical(self):
        timezone = self.dt.tzname()
        if timezone == 'UTC' or self.dt.tzinfo == UTC:
            return self.dt.strftime("%Y%m%dT%H%M%SZ")
        elif timezone:
            self.params.update({'TZID': timezone})
            return "TZID=%s;%s" % (timezone, self.dt.strftime("%Y%m%dT%H%M%S"))
        return self.dt.strftime("%Y%m%dT%H%M%S")

    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        # TODO: ical string should better contain also the TZID property.deleter(

        if timezone:
            timezone = timezone_from_string(timezone)

        try:
            timetuple = map(int, ((
                ical[:4],       # year
                ical[4:6],      # month
                ical[6:8],      # day
                ical[9:11],     # hour
                ical[11:13],    # minute
                ical[13:15],    # second
                )))
            if timezone:
                return datetime(tzinfo=timezone, *timetuple)
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                timetuple += [0, UTC]
                return datetime(*timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical
    from_ical = staticmethod(from_ical)