# This module is a very stripped down version of the dateutil # package for when dateutil has not been installed. As a replacement # for dateutil.parser.parse, the parsing methods from # http://blog.mfabrik.com/2008/06/30/relativity-of-time-shortcomings-in-python-datetime-and-workaround/ #As such, the following copyrights and licenses applies: # dateutil - Extensions to the standard python 2.3+ datetime module. # # Copyright (c) 2003-2011 - Gustavo Niemeyer # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # fixed_dateime # # Copyright (c) 2008, Red Innovation Ltd., Finland # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Red Innovation nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY RED INNOVATION ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL RED INNOVATION BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import re import math import datetime ZERO = datetime.timedelta(0) try: from dateutil.parser import parse as parse_iso from dateutil.tz import tzoffset, tzutc except: # As a stopgap, define the two timezones here based # on the dateutil code. class tzutc(datetime.tzinfo): def utcoffset(self, dt): return ZERO def dst(self, dt): return ZERO def tzname(self, dt): return "UTC" def __eq__(self, other): return (isinstance(other, tzutc) or (isinstance(other, tzoffset) and other._offset == ZERO)) def __ne__(self, other): return not self.__eq__(other) def __repr__(self): return "%s()" % self.__class__.__name__ __reduce__ = object.__reduce__ class tzoffset(datetime.tzinfo): def __init__(self, name, offset): self._name = name self._offset = datetime.timedelta(minutes=offset) def utcoffset(self, dt): return self._offset def dst(self, dt): return ZERO def tzname(self, dt): return self._name def __eq__(self, other): return (isinstance(other, tzoffset) and self._offset == other._offset) def __ne__(self, other): return not self.__eq__(other) def __repr__(self): return "%s(%s, %s)" % (self.__class__.__name__, repr(self._name), self._offset.days*86400+self._offset.seconds) __reduce__ = object.__reduce__ _fixed_offset_tzs = { } UTC = tzutc() def _get_fixed_offset_tz(offsetmins): """For internal use only: Returns a tzinfo with the given fixed offset. This creates only one instance for each offset; the zones are kept in a dictionary""" if offsetmins == 0: return UTC if not offsetmins in _fixed_offset_tzs: if offsetmins < 0: sign = '-' absoff = -offsetmins else: sign = '+' absoff = offsetmins name = "UTC%s%02d:%02d" % (sign, int(absoff / 60), absoff % 60) inst = tzoffset(name,offsetmins) _fixed_offset_tzs[offsetmins] = inst return _fixed_offset_tzs[offsetmins] _iso8601_parser = re.compile(""" ^ (?P [0-9]{4})?(?P-?)? (?P[0-9]{2})?(?P=ymdsep)? (?P [0-9]{2})? (?P