diff options
author | Gerhard Weis <g.weis@griffith.edu.au> | 2014-02-27 11:13:44 +1000 |
---|---|---|
committer | Gerhard Weis <g.weis@griffith.edu.au> | 2014-02-27 11:13:44 +1000 |
commit | 80a8e6d13778252f626dfb8d7503648335e23482 (patch) | |
tree | df00a07909317af1de21bf7201bb194e1e2f2bc8 | |
parent | 308302303068ecd149957a958c9d71625771c0f9 (diff) | |
download | isodate-80a8e6d13778252f626dfb8d7503648335e23482.tar.gz |
make flake happy
-rw-r--r-- | src/isodate/__init__.py | 23 | ||||
-rw-r--r-- | src/isodate/duration.py | 46 | ||||
-rw-r--r-- | src/isodate/isodates.py | 49 | ||||
-rw-r--r-- | src/isodate/isodatetime.py | 16 | ||||
-rw-r--r-- | src/isodate/isoduration.py | 29 | ||||
-rw-r--r-- | src/isodate/isoerror.py | 5 | ||||
-rw-r--r-- | src/isodate/isostrf.py | 46 | ||||
-rw-r--r-- | src/isodate/isotime.py | 3 | ||||
-rw-r--r-- | src/isodate/isotzinfo.py | 23 | ||||
-rw-r--r-- | src/isodate/tests/__init__.py | 1 | ||||
-rw-r--r-- | src/isodate/tests/test_date.py | 23 | ||||
-rw-r--r-- | src/isodate/tests/test_datetime.py | 8 | ||||
-rw-r--r-- | src/isodate/tests/test_duration.py | 264 | ||||
-rw-r--r-- | src/isodate/tests/test_pickle.py | 1 | ||||
-rw-r--r-- | src/isodate/tests/test_strf.py | 17 | ||||
-rw-r--r-- | src/isodate/tests/test_time.py | 24 | ||||
-rw-r--r-- | src/isodate/tzinfo.py | 13 |
17 files changed, 329 insertions, 262 deletions
diff --git a/src/isodate/__init__.py b/src/isodate/__init__.py index 091af0a..26604c2 100644 --- a/src/isodate/__init__.py +++ b/src/isodate/__init__.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -28,12 +28,12 @@ Import all essential functions and constants to re-export them here for easy access. -This module contains also various pre-defined ISO 8601 format strings. +This module contains also various pre-defined ISO 8601 format strings. ''' from isodate.isodates import parse_date, date_isoformat from isodate.isotime import parse_time, time_isoformat from isodate.isodatetime import parse_datetime, datetime_isoformat -from isodate.isoduration import parse_duration, duration_isoformat, Duration +from isodate.isoduration import parse_duration, duration_isoformat from isodate.isoerror import ISO8601Error from isodate.isotzinfo import parse_tzinfo, tz_isoformat from isodate.tzinfo import UTC, FixedOffset, LOCAL @@ -53,3 +53,18 @@ from isodate.isostrf import DT_BAS_ORD_COMPLETE, DT_EXT_ORD_COMPLETE from isodate.isostrf import DT_BAS_WEEK_COMPLETE, DT_EXT_WEEK_COMPLETE from isodate.isostrf import D_DEFAULT, D_WEEK, D_ALT_EXT, D_ALT_BAS from isodate.isostrf import D_ALT_BAS_ORD, D_ALT_EXT_ORD + +__all__ = (parse_date, date_isoformat, parse_time, time_isoformat, + parse_datetime, datetime_isoformat, parse_duration, + duration_isoformat, ISO8601Error, parse_tzinfo, + tz_isoformat, UTC, FixedOffset, LOCAL, Duration, + strftime, DATE_BAS_COMPLETE, DATE_BAS_ORD_COMPLETE, + DATE_BAS_WEEK, DATE_BAS_WEEK_COMPLETE, DATE_CENTURY, + DATE_EXT_COMPLETE, DATE_EXT_ORD_COMPLETE, DATE_EXT_WEEK, + DATE_EXT_WEEK_COMPLETE, DATE_MONTH, DATE_YEAR, + TIME_BAS_COMPLETE, TIME_BAS_MINUTE, TIME_EXT_COMPLETE, + TIME_EXT_MINUTE, TIME_HOUR, TZ_BAS, TZ_EXT, TZ_HOUR, + DT_BAS_COMPLETE, DT_EXT_COMPLETE, DT_BAS_ORD_COMPLETE, + DT_EXT_ORD_COMPLETE, DT_BAS_WEEK_COMPLETE, + DT_EXT_WEEK_COMPLETE, D_DEFAULT, D_WEEK, D_ALT_EXT, + D_ALT_BAS, D_ALT_BAS_ORD, D_ALT_EXT_ORD) diff --git a/src/isodate/duration.py b/src/isodate/duration.py index 4484919..62b14ca 100644 --- a/src/isodate/duration.py +++ b/src/isodate/duration.py @@ -40,8 +40,8 @@ def fquotmod(val, low, high): ''' # assumes that all the maths is done with Decimals. - # divmod for Decimal uses truncate instead of floor as builtin divmod, so we have - # to do it manually here. + # divmod for Decimal uses truncate instead of floor as builtin + # divmod, so we have to do it manually here. a, b = val - low, high - low div = (a / b).to_integral(ROUND_FLOOR) mod = a - div * b @@ -124,9 +124,9 @@ class Duration(object): Return a string suitable for repr(x) calls. ''' return "%s.%s(%d, %d, %d, years=%d, months=%d)" % ( - self.__class__.__module__, self.__class__.__name__, - self.tdelta.days, self.tdelta.seconds, - self.tdelta.microseconds, self.years, self.months) + self.__class__.__module__, self.__class__.__name__, + self.tdelta.days, self.tdelta.seconds, + self.tdelta.microseconds, self.years, self.months) def __neg__(self): """ @@ -153,8 +153,10 @@ class Duration(object): newduration.tdelta = self.tdelta + other.tdelta return newduration if isinstance(other, (date, datetime)): - if (not( float(self.years).is_integer() and float(self.months).is_integer())): - raise ValueError('fractional years or months not supported for date calculations') + if (not(float(self.years).is_integer() + and float(self.months).is_integer())): + raise ValueError('fractional years or months not supported' + ' for date calculations') newmonth = other.month + self.months carry, newmonth = fquotmod(newmonth, 1, 13) newyear = other.year + self.years + carry @@ -177,8 +179,10 @@ class Duration(object): newduration.tdelta = self.tdelta + other return newduration if isinstance(other, (date, datetime)): - if (not( float(self.years).is_integer() and float(self.months).is_integer())): - raise ValueError('fractional years or months not supported for date calculations') + if (not(float(self.years).is_integer() + and float(self.months).is_integer())): + raise ValueError('fractional years or months not supported' + ' for date calculations') newmonth = other.month + self.months carry, newmonth = fquotmod(newmonth, 1, 13) newyear = other.year + self.years + carry @@ -216,8 +220,10 @@ class Duration(object): ''' #print '__rsub__:', self, other if isinstance(other, (date, datetime)): - if (not( float(self.years).is_integer() and float(self.months).is_integer())): - raise ValueError('fractional years or months not supported for date calculations') + if (not(float(self.years).is_integer() + and float(self.months).is_integer())): + raise ValueError('fractional years or months not supported' + ' for date calculations') newmonth = other.month - self.months carry, newmonth = fquotmod(newmonth, 1, 13) newyear = other.year - self.years + carry @@ -240,13 +246,14 @@ class Duration(object): If the years, month part and the timedelta part are both equal, then the two Durations are considered equal. ''' - if (isinstance(other, timedelta) and - self.years == 0 and self.months == 0): + if ((isinstance(other, timedelta) and + self.years == 0 and self.months == 0)): return self.tdelta == other if not isinstance(other, Duration): return NotImplemented - if ((self.years * 12 + self.months) == - (other.years * 12 + other.months) and self.tdelta == other.tdelta): + if (((self.years * 12 + self.months) == + (other.years * 12 + other.months) + and self.tdelta == other.tdelta)): return True return False @@ -255,12 +262,15 @@ class Duration(object): If the years, month part or the timedelta part is not equal, then the two Durations are considered not equal. ''' - if isinstance(other, timedelta) and self.years == 0 and self.months == 0: + if ((isinstance(other, timedelta) + and self.years == 0 + and self.months == 0)): return self.tdelta != other if not isinstance(other, Duration): return NotImplemented - if ((self.years * 12 + self.months) != - (other.years * 12 + other.months) or self.tdelta != other.tdelta): + if (((self.years * 12 + self.months) != + (other.years * 12 + other.months) + or self.tdelta != other.tdelta)): return True return False diff --git a/src/isodate/isodates.py b/src/isodate/isodates.py index 8bafa20..aee7417 100644 --- a/src/isodate/isodates.py +++ b/src/isodate/isodates.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -42,18 +42,19 @@ DATE_REGEX_CACHE = {} # A dictionary to cache pre-compiled regular expressions. # A set of regular expressions is identified, by number of year digits allowed # and whether a plus/minus sign is required or not. (This option is changeable -# only for 4 digit years). +# only for 4 digit years). + def build_date_regexps(yeardigits=4, expanded=False): ''' Compile set of regular expressions to parse ISO dates. The expressions will be created only if they are not already in REGEX_CACHE. - + It is necessary to fix the number of year digits, else it is not possible to automatically distinguish between various ISO date formats. - + ISO 8601 allows more than 4 digit years, on prior agreement, but then a +/- - sign is required (expanded format). To support +/- sign for 4 digit years, + sign is required (expanded format). To support +/- sign for 4 digit years, the expanded parameter needs to be set to True. ''' if yeardigits != 4: @@ -73,7 +74,7 @@ def build_date_regexps(yeardigits=4, expanded=False): % (sign, yeardigits))) # YYYYMMDD or +- YYYYYYMMDD... basic date format cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" - r"(?P<month>[0-9]{2})(?P<day>[0-9]{2})" + r"(?P<month>[0-9]{2})(?P<day>[0-9]{2})" % (sign, yeardigits))) # 2. complete week dates: # YYYY-Www-D or +-YYYYYY-Www-D ... extended week date @@ -98,7 +99,7 @@ def build_date_regexps(yeardigits=4, expanded=False): cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" r"-W(?P<week>[0-9]{2})" % (sign, yeardigits))) - # YYYYWww or +-YYYYYYWww ... basic reduced accuracy week date + # YYYYWww or +-YYYYYYWww ... basic reduced accuracy week date cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})W" r"(?P<week>[0-9]{2})" % (sign, yeardigits))) @@ -120,18 +121,19 @@ def build_date_regexps(yeardigits=4, expanded=False): DATE_REGEX_CACHE[(yeardigits, expanded)] = cache_entry return DATE_REGEX_CACHE[(yeardigits, expanded)] + def parse_date(datestring, yeardigits=4, expanded=False): ''' Parse an ISO 8601 date string into a datetime.date object. - + As the datetime.date implementation is limited to dates starting from 0001-01-01, negative dates (BC) and year 0 can not be parsed by this method. - + For incomplete dates, this method chooses the first day for it. For - instance if only a century is given, this method returns the 1st of + instance if only a century is given, this method returns the 1st of January in year 1 of this century. - + supported formats: (expanded formats are shown with 6 digits for year) YYYYMMDD +-YYYYYYMMDD basic complete date YYYY-MM-DD +-YYYYYY-MM-DD extended complete date @@ -149,10 +151,10 @@ def parse_date(datestring, yeardigits=4, expanded=False): @param yeardigits: how many digits are used to represent a year @param expanded: if True then +/- signs are allowed. This parameter is forced to True, if yeardigits != 4 - + @return: a datetime.date instance represented by datestring @raise ISO8601Error: if this function can not parse the datestring - @raise ValueError: if datestring can not be represented by datetime.date + @raise ValueError: if datestring can not be represented by datetime.date ''' if yeardigits != 4: expanded = True @@ -163,10 +165,10 @@ def parse_date(datestring, yeardigits=4, expanded=False): groups = match.groupdict() # sign, century, year, month, week, day, # FIXME: negative dates not possible with python standard types - sign = (groups['sign'] == '-' and -1) or 1 + sign = (groups['sign'] == '-' and -1) or 1 if 'century' in groups: return date(sign * (int(groups['century']) * 100 + 1), 1, 1) - if not 'month' in groups: # weekdate or ordinal date + if not 'month' in groups: # weekdate or ordinal date ret = date(sign * int(groups['year']), 1, 1) if 'week' in groups: isotuple = ret.isocalendar() @@ -175,10 +177,10 @@ def parse_date(datestring, yeardigits=4, expanded=False): else: days = 1 # if first week in year, do weeks-1 - return ret + timedelta(weeks=int(groups['week']) - - (((isotuple[1] == 1) and 1) or 0), - days = -isotuple[2] + days) - elif 'day' in groups: # ordinal date + return ret + timedelta(weeks=int(groups['week']) - + (((isotuple[1] == 1) and 1) or 0), + days=-isotuple[2] + days) + elif 'day' in groups: # ordinal date return ret + timedelta(days=int(groups['day'])-1) else: # year date return ret @@ -187,14 +189,15 @@ def parse_date(datestring, yeardigits=4, expanded=False): day = 1 else: day = int(groups['day']) - return date(sign * int(groups['year']), + return date(sign * int(groups['year']), int(groups['month']) or 1, day) raise ISO8601Error('Unrecognised ISO 8601 date format: %r' % datestring) + def date_isoformat(tdate, format=DATE_EXT_COMPLETE, yeardigits=4): ''' - Format date strings. - + Format date strings. + This method is just a wrapper around isodate.isostrf.strftime and uses Date-Extended-Complete as default format. ''' diff --git a/src/isodate/isodatetime.py b/src/isodate/isodatetime.py index 7e4d570..147474b 100644 --- a/src/isodate/isodatetime.py +++ b/src/isodate/isodatetime.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -37,10 +37,11 @@ from isodate.isostrf import DATE_EXT_COMPLETE, TIME_EXT_COMPLETE, TZ_EXT from isodate.isodates import parse_date from isodate.isotime import parse_time + def parse_datetime(datetimestring): ''' Parses ISO 8601 date-times into datetime.datetime objects. - + This function uses parse_date and parse_time to do the job, so it allows more combinations of date and time representations, than the actual ISO 8601:2004 standard allows. @@ -50,11 +51,12 @@ def parse_datetime(datetimestring): tmptime = parse_time(timestring) return datetime.combine(tmpdate, tmptime) -def datetime_isoformat(tdt, format=DATE_EXT_COMPLETE + 'T' + - TIME_EXT_COMPLETE + TZ_EXT): + +def datetime_isoformat(tdt, format=DATE_EXT_COMPLETE + 'T' + + TIME_EXT_COMPLETE + TZ_EXT): ''' - Format datetime strings. - + Format datetime strings. + This method is just a wrapper around isodate.isostrf.strftime and uses Extended-Complete as default format. ''' diff --git a/src/isodate/isoduration.py b/src/isodate/isoduration.py index 97affdc..a229186 100644 --- a/src/isodate/isoduration.py +++ b/src/isodate/isoduration.py @@ -39,14 +39,15 @@ from isodate.isoerror import ISO8601Error from isodate.isodatetime import parse_datetime from isodate.isostrf import strftime, D_DEFAULT -ISO8601_PERIOD_REGEX = re.compile(r"^(?P<sign>[+-])?" - r"P(?P<years>[0-9]+([,.][0-9]+)?Y)?" - r"(?P<months>[0-9]+([,.][0-9]+)?M)?" - r"(?P<weeks>[0-9]+([,.][0-9]+)?W)?" - r"(?P<days>[0-9]+([,.][0-9]+)?D)?" - r"((?P<separator>T)(?P<hours>[0-9]+([,.][0-9]+)?H)?" - r"(?P<minutes>[0-9]+([,.][0-9]+)?M)?" - r"(?P<seconds>[0-9]+([,.][0-9]+)?S)?)?$") +ISO8601_PERIOD_REGEX = re.compile( + r"^(?P<sign>[+-])?" + r"P(?P<years>[0-9]+([,.][0-9]+)?Y)?" + r"(?P<months>[0-9]+([,.][0-9]+)?M)?" + r"(?P<weeks>[0-9]+([,.][0-9]+)?W)?" + r"(?P<days>[0-9]+([,.][0-9]+)?D)?" + r"((?P<separator>T)(?P<hours>[0-9]+([,.][0-9]+)?H)?" + r"(?P<minutes>[0-9]+([,.][0-9]+)?M)?" + r"(?P<seconds>[0-9]+([,.][0-9]+)?S)?)?$") # regular expression to parse ISO duartion strings. @@ -107,7 +108,8 @@ def parse_duration(datestring): if key in ('years', 'months'): groups[key] = Decimal(groups[key][:-1].replace(',', '.')) else: - # these values are passed into a timedelta object, which works with floats. + # these values are passed into a timedelta object, + # which works with floats. groups[key] = float(groups[key][:-1].replace(',', '.')) if groups["years"] == 0 and groups["months"] == 0: ret = timedelta(days=groups["days"], hours=groups["hours"], @@ -134,10 +136,11 @@ def duration_isoformat(tduration, format=D_DEFAULT): ''' # TODO: implement better decision for negative Durations. # should be done in Duration class in consistent way with timedelta. - if ((isinstance(tduration, Duration) and (tduration.years < 0 or - tduration.months < 0 or - tduration.tdelta < timedelta(0))) - or (isinstance(tduration, timedelta) and (tduration < timedelta(0)))): + if (((isinstance(tduration, Duration) + and (tduration.years < 0 or tduration.months < 0 + or tduration.tdelta < timedelta(0))) + or (isinstance(tduration, timedelta) + and (tduration < timedelta(0))))): ret = '-' else: ret = '' diff --git a/src/isodate/isoerror.py b/src/isodate/isoerror.py index edbc5aa..e7b211b 100644 --- a/src/isodate/isoerror.py +++ b/src/isodate/isoerror.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -28,5 +28,6 @@ This module defines all exception classes in the whole package. ''' + class ISO8601Error(ValueError): '''Raised when the given ISO string can not be parsed.''' diff --git a/src/isodate/isostrf.py b/src/isodate/isostrf.py index 5f3169f..1afc810 100644 --- a/src/isodate/isostrf.py +++ b/src/isodate/isostrf.py @@ -69,10 +69,10 @@ DT_EXT_COMPLETE = DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + TZ_EXT DT_BAS_COMPLETE = DATE_BAS_COMPLETE + 'T' + TIME_BAS_COMPLETE + TZ_BAS DT_EXT_ORD_COMPLETE = DATE_EXT_ORD_COMPLETE + 'T' + TIME_EXT_COMPLETE + TZ_EXT DT_BAS_ORD_COMPLETE = DATE_BAS_ORD_COMPLETE + 'T' + TIME_BAS_COMPLETE + TZ_BAS -DT_EXT_WEEK_COMPLETE = DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_COMPLETE +\ - TZ_EXT -DT_BAS_WEEK_COMPLETE = DATE_BAS_WEEK_COMPLETE + 'T' + TIME_BAS_COMPLETE +\ - TZ_BAS +DT_EXT_WEEK_COMPLETE = (DATE_EXT_WEEK_COMPLETE + 'T' + + TIME_EXT_COMPLETE + TZ_EXT) +DT_BAS_WEEK_COMPLETE = (DATE_BAS_WEEK_COMPLETE + 'T' + + TIME_BAS_COMPLETE + TZ_BAS) # Duration formts D_DEFAULT = 'P%P' @@ -86,17 +86,19 @@ STRF_DT_MAP = {'%d': lambda tdt, yds: '%02d' % tdt.day, '%f': lambda tdt, yds: '%06d' % tdt.microsecond, '%H': lambda tdt, yds: '%02d' % tdt.hour, '%j': lambda tdt, yds: '%03d' % (tdt.toordinal() - - date(tdt.year, 1, 1).toordinal() + - 1), + date(tdt.year, + 1, 1).toordinal() + + 1), '%m': lambda tdt, yds: '%02d' % tdt.month, '%M': lambda tdt, yds: '%02d' % tdt.minute, '%S': lambda tdt, yds: '%02d' % tdt.second, '%w': lambda tdt, yds: '%1d' % tdt.isoweekday(), '%W': lambda tdt, yds: '%02d' % tdt.isocalendar()[1], - '%Y': lambda tdt, yds: (((yds != 4) and '+') or '') +\ - (('%%0%dd' % yds) % tdt.year), - '%C': lambda tdt, yds: (((yds != 4) and '+') or '') +\ - (('%%0%dd' % (yds - 2)) % (tdt.year / 100)), + '%Y': lambda tdt, yds: (((yds != 4) and '+') or '') + + (('%%0%dd' % yds) % tdt.year), + '%C': lambda tdt, yds: (((yds != 4) and '+') or '') + + (('%%0%dd' % (yds - 2)) % + (tdt.year / 100)), '%h': lambda tdt, yds: tz_isoformat(tdt, '%h'), '%Z': lambda tdt, yds: tz_isoformat(tdt, '%Z'), '%z': lambda tdt, yds: tz_isoformat(tdt, '%z'), @@ -109,11 +111,11 @@ STRF_D_MAP = {'%d': lambda tdt, yds: '%02d' % tdt.days, '%M': lambda tdt, yds: '%02d' % ((tdt.seconds / 60) % 60), '%S': lambda tdt, yds: '%02d' % (tdt.seconds % 60), '%W': lambda tdt, yds: '%02d' % (abs(tdt.days / 7)), - '%Y': lambda tdt, yds: (((yds != 4) and '+') or '') +\ - (('%%0%dd' % yds) % tdt.years), - '%C': lambda tdt, yds: (((yds != 4) and '+') or '') +\ - (('%%0%dd' % (yds - 2)) % - (tdt.years / 100)), + '%Y': lambda tdt, yds: (((yds != 4) and '+') or '') + + (('%%0%dd' % yds) % tdt.years), + '%C': lambda tdt, yds: (((yds != 4) and '+') or '') + + (('%%0%dd' % (yds - 2)) % + (tdt.years / 100)), '%%': lambda tdt, yds: '%'} @@ -183,24 +185,28 @@ def _strfdt(tdt, format, yeardigits=4): def strftime(tdt, format, yeardigits=4): - ''' - Directive Meaning Notes + '''Directive Meaning Notes %d Day of the month as a decimal number [01,31]. - %f Microsecond as a decimal number [0,999999], zero-padded on the left (1) + %f Microsecond as a decimal number [0,999999], zero-padded + on the left (1) %H Hour (24-hour clock) as a decimal number [00,23]. %j Day of the year as a decimal number [001,366]. %m Month as a decimal number [01,12]. %M Minute as a decimal number [00,59]. %S Second as a decimal number [00,61]. (3) %w Weekday as a decimal number [0(Monday),6]. - %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (4) + %W Week number of the year (Monday as the first day of the week) + as a decimal number [00,53]. All days in a new year preceding the + first Monday are considered to be in week 0. (4) %Y Year with century as a decimal number. [0000,9999] %C Century as a decimal number. [00,99] - %z UTC offset in the form +HHMM or -HHMM (empty string if the the object is naive). (5) + %z UTC offset in the form +HHMM or -HHMM (empty string if the + object is naive). (5) %Z Time zone name (empty string if the object is naive). %P ISO8601 duration format. %p ISO8601 duration format in weeks. %% A literal '%' character. + ''' if isinstance(tdt, (timedelta, Duration)): return _strfduration(tdt, format, yeardigits) diff --git a/src/isodate/isotime.py b/src/isodate/isotime.py index 7ded2d4..2b268d0 100644 --- a/src/isodate/isotime.py +++ b/src/isodate/isotime.py @@ -129,7 +129,8 @@ def parse_time(timestring): # int(...) ... no rounding # to_integral() ... rounding return time(int(groups['hour']), int(groups['minute']), - int(second), int(microsecond.to_integral()), tzinfo) + int(second), int(microsecond.to_integral()), + tzinfo) if 'minute' in groups: minute = Decimal(groups['minute']) second = (minute - int(minute)) * 60 diff --git a/src/isodate/isotzinfo.py b/src/isodate/isotzinfo.py index 97dbe8c..263afd7 100644 --- a/src/isodate/isotzinfo.py +++ b/src/isodate/isotzinfo.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -27,7 +27,7 @@ ''' This module provides an ISO 8601:2004 time zone info parser. -It offers a function to parse the time zone offset as specified by ISO 8601. +It offers a function to parse the time zone offset as specified by ISO 8601. ''' import re @@ -39,10 +39,11 @@ TZ_REGEX = r"(?P<tzname>(Z|(?P<tzsign>[+-])"\ TZ_RE = re.compile(TZ_REGEX) + def build_tzinfo(tzname, tzsign='+', tzhour=0, tzmin=0): ''' create a tzinfo instance according to given parameters. - + tzname: 'Z' ... return UTC '' | None ... return None @@ -55,10 +56,11 @@ def build_tzinfo(tzname, tzsign='+', tzhour=0, tzmin=0): tzsign = ((tzsign == '-') and -1) or 1 return FixedOffset(tzsign * tzhour, tzsign * tzmin, tzname) + def parse_tzinfo(tzstring): ''' Parses ISO 8601 time zone designators to tzinfo objecs. - + A time zone designator can be in the following format: no designator indicates local time zone Z UTC @@ -69,19 +71,20 @@ def parse_tzinfo(tzstring): match = TZ_RE.match(tzstring) if match: groups = match.groupdict() - return build_tzinfo(groups['tzname'], groups['tzsign'], - int(groups['tzhour'] or 0), + return build_tzinfo(groups['tzname'], groups['tzsign'], + int(groups['tzhour'] or 0), int(groups['tzmin'] or 0)) raise ISO8601Error('%s not a valid time zone info' % tzstring) + def tz_isoformat(dt, format='%Z'): ''' - return time zone offset ISO 8601 formatted. + return time zone offset ISO 8601 formatted. The various ISO formats can be chosen with the format parameter. - + if tzinfo is None returns '' if tzinfo is UTC returns 'Z' - else the offset is rendered to the given format. + else the offset is rendered to the given format. format: %h ... +-HH %z ... +-HHMM diff --git a/src/isodate/tests/__init__.py b/src/isodate/tests/__init__.py index bc1867d..09dba2e 100644 --- a/src/isodate/tests/__init__.py +++ b/src/isodate/tests/__init__.py @@ -32,6 +32,7 @@ import unittest from isodate.tests import (test_date, test_time, test_datetime, test_duration, test_strf, test_pickle) + def test_suite(): ''' Return a new TestSuite instance consisting of all available TestSuites. diff --git a/src/isodate/tests/test_date.py b/src/isodate/tests/test_date.py index 3a1b4a6..fdc1043 100644 --- a/src/isodate/tests/test_date.py +++ b/src/isodate/tests/test_date.py @@ -14,11 +14,11 @@ # 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" +# 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 +# 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 @@ -66,20 +66,21 @@ TEST_CASES = {4: [('19', date(1901, 1, 1), DATE_CENTURY), ('+001985W15', date(1985, 4, 8), DATE_BAS_WEEK), ('+001985-W15', date(1985, 4, 8), DATE_EXT_WEEK)]} + def create_testcase(yeardigits, datestring, expectation, format): ''' Create a TestCase class for a specific test. - + This allows having a separate TestCase for each test tuple from the TEST_CASES list, so that a failed test won't stop other tests. ''' - + class TestDate(unittest.TestCase): ''' A test case template to parse an ISO date string into a date object. ''' - + def test_parse(self): ''' Parse an ISO date string and compare it to the expected value. @@ -90,7 +91,7 @@ def create_testcase(yeardigits, datestring, expectation, format): else: result = parse_date(datestring, yeardigits) self.assertEqual(result, expectation) - + def test_format(self): ''' Take date object and create ISO string from it. @@ -98,15 +99,16 @@ def create_testcase(yeardigits, datestring, expectation, format): ''' if expectation is None: self.assertRaises(AttributeError, - date_isoformat, expectation, format, - yeardigits) + date_isoformat, expectation, format, + yeardigits) else: self.assertEqual(date_isoformat(expectation, format, yeardigits), datestring) - + return unittest.TestLoader().loadTestsFromTestCase(TestDate) + def test_suite(): ''' Construct a TestSuite instance for all test cases. @@ -118,9 +120,10 @@ def test_suite(): expectation, format)) return suite + # load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() - + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff --git a/src/isodate/tests/test_datetime.py b/src/isodate/tests/test_datetime.py index f6aaa51..73b1982 100644 --- a/src/isodate/tests/test_datetime.py +++ b/src/isodate/tests/test_datetime.py @@ -82,7 +82,7 @@ TEST_CASES = [('19850412T1015', datetime(1985, 4, 12, 10, 15), datetime(2012, 10, 30, 8, 55, 22, 123456, tzinfo=UTC), DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + '.%f' + TZ_BAS, '2012-10-30T08:55:22.123456Z') - ] + ] def create_testcase(datetimestring, expectation, format, output): @@ -127,12 +127,14 @@ def test_suite(): ''' suite = unittest.TestSuite() for datetimestring, expectation, format, output in TEST_CASES: - suite.addTest(create_testcase(datetimestring, expectation, format, output)) + suite.addTest(create_testcase(datetimestring, expectation, + format, output)) return suite + # load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() - + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff --git a/src/isodate/tests/test_duration.py b/src/isodate/tests/test_duration.py index e69ae17..c664120 100644 --- a/src/isodate/tests/test_duration.py +++ b/src/isodate/tests/test_duration.py @@ -55,7 +55,7 @@ PARSE_TEST_CASES = {'P18Y9M4DT11H9M8S': (Duration(4, 8, 0, 0, 9, 11, 0, 9, 18), '-P2.2W': (timedelta(weeks=-2.2), D_DEFAULT, '-P15DT9H36M'), 'P1DT2H3M4S': (timedelta(days=1, hours=2, minutes=3, - seconds=4), D_DEFAULT, None), + seconds=4), D_DEFAULT, None), 'P1DT2H3M': (timedelta(days=1, hours=2, minutes=3), D_DEFAULT, None), 'P1DT2H': (timedelta(days=1, hours=2), D_DEFAULT, None), @@ -98,137 +98,138 @@ MATH_TEST_CASES = (('P5Y7M1DT9H45M16.72S', 'PT27M24.68S', ('PT1H1.95S', 'P1332DT55M0.33S', 'P1332DT1H55M2.28S', '-P1331DT23H54M58.38S', False)) + # A list of test cases to test addition and subtraction of date/datetime # and Duration objects. They are tested against the results of an # equal long timedelta duration. -DATE_TEST_CASES = ( (date(2008, 2, 29), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (date(2008, 1, 31), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (datetime(2008, 2, 29), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (datetime(2008, 1, 31), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (datetime(2008, 4, 21), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (datetime(2008, 5, 5), - timedelta(days=10, hours=12, minutes=20), - Duration(days=10, hours=12, minutes=20)), - (datetime(2000, 1, 1), - timedelta(hours=-33), - Duration(hours=-33)), - (datetime(2008, 5, 5), - Duration(years=1, months=1, days=10, hours=12, - minutes=20), - Duration(months=13, days=10, hours=12, minutes=20)), - (datetime(2000, 3, 30), - Duration(years=1, months=1, days=10, hours=12, - minutes=20), - Duration(months=13, days=10, hours=12, minutes=20)), - ) +DATE_TEST_CASES = ((date(2008, 2, 29), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (date(2008, 1, 31), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (datetime(2008, 2, 29), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (datetime(2008, 1, 31), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (datetime(2008, 4, 21), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (datetime(2008, 5, 5), + timedelta(days=10, hours=12, minutes=20), + Duration(days=10, hours=12, minutes=20)), + (datetime(2000, 1, 1), + timedelta(hours=-33), + Duration(hours=-33)), + (datetime(2008, 5, 5), + Duration(years=1, months=1, days=10, hours=12, + minutes=20), + Duration(months=13, days=10, hours=12, minutes=20)), + (datetime(2000, 3, 30), + Duration(years=1, months=1, days=10, hours=12, + minutes=20), + Duration(months=13, days=10, hours=12, minutes=20)), + ) # A list of test cases of additon of date/datetime and Duration. The results # are compared against a given expected result. DATE_CALC_TEST_CASES = ( - (date(2000, 2, 1), - Duration(years=1, months=1), - date(2001, 3, 1)), - (date(2000, 2, 29), - Duration(years=1, months=1), - date(2001, 3, 29)), - (date(2000, 2, 29), - Duration(years=1), - date(2001, 2, 28)), - (date(1996, 2, 29), - Duration(years=4), - date(2000, 2, 29)), - (date(2096, 2, 29), - Duration(years=4), - date(2100, 2, 28)), - (date(2000, 2, 1), - Duration(years=-1, months=-1), - date(1999, 1, 1)), - (date(2000, 2, 29), - Duration(years=-1, months=-1), - date(1999, 1, 29)), - (date(2000, 2, 1), - Duration(years=1, months=1, days=1), - date(2001, 3, 2)), - (date(2000, 2, 29), - Duration(years=1, months=1, days=1), - date(2001, 3, 30)), - (date(2000, 2, 29), - Duration(years=1, days=1), - date(2001, 3, 1)), - (date(1996, 2, 29), - Duration(years=4, days=1), - date(2000, 3, 1)), - (date(2096, 2, 29), - Duration(years=4, days=1), - date(2100, 3, 1)), - (date(2000, 2, 1), - Duration(years=-1, months=-1, days=-1), - date(1998, 12, 31)), - (date(2000, 2, 29), - Duration(years=-1, months=-1, days=-1), - date(1999, 1, 28)), - (date(2001, 4, 1), - Duration(years=-1, months=-1, days=-1), - date(2000, 2, 29)), - (date(2000, 4, 1), - Duration(years=-1, months=-1, days=-1), - date(1999, 2, 28)), - (Duration(years=1, months=2), - Duration(years=0, months=0, days=1), - Duration(years=1, months=2, days=1)), - (Duration(years=-1, months=-1, days=-1), - date(2000, 4, 1), - date(1999, 2, 28)), - (Duration(years=1, months=1, weeks=5), - date(2000, 1, 30), - date(2001, 4, 4)), - (parse_duration("P1Y1M5W"), - date(2000, 1, 30), - date(2001, 4, 4)), - (parse_duration("P0.5Y"), - date(2000, 1, 30), - None), - (Duration(years=1, months=1, hours=3), - datetime(2000, 1, 30, 12, 15, 00), - datetime(2001, 2, 28, 15, 15, 00)), - (parse_duration("P1Y1MT3H"), - datetime(2000, 1, 30, 12, 15, 00), - datetime(2001, 2, 28, 15, 15, 00)), - (Duration(years=1, months=2), - timedelta(days=1), - Duration(years=1, months=2, days=1)), - (timedelta(days=1), - Duration(years=1, months=2), - Duration(years=1, months=2, days=1)), - (datetime(2008, 1, 1, 0, 2), - Duration(months=1), - datetime(2008, 2, 1, 0, 2)), - (datetime.strptime("200802", "%Y%M"), - parse_duration("P1M"), - datetime(2008, 2, 1, 0, 2)), - (datetime(2008, 2, 1), - Duration(months=1), - datetime(2008, 3, 1)), - (datetime.strptime("200802", "%Y%m"), - parse_duration("P1M"), - datetime(2008, 3, 1)), - # (date(2000, 1, 1), - # Duration(years=1.5), - # date(2001, 6, 1)), - # (date(2000, 1, 1), - # Duration(years=1, months=1.5), - # date(2001, 2, 14)), - ) + (date(2000, 2, 1), + Duration(years=1, months=1), + date(2001, 3, 1)), + (date(2000, 2, 29), + Duration(years=1, months=1), + date(2001, 3, 29)), + (date(2000, 2, 29), + Duration(years=1), + date(2001, 2, 28)), + (date(1996, 2, 29), + Duration(years=4), + date(2000, 2, 29)), + (date(2096, 2, 29), + Duration(years=4), + date(2100, 2, 28)), + (date(2000, 2, 1), + Duration(years=-1, months=-1), + date(1999, 1, 1)), + (date(2000, 2, 29), + Duration(years=-1, months=-1), + date(1999, 1, 29)), + (date(2000, 2, 1), + Duration(years=1, months=1, days=1), + date(2001, 3, 2)), + (date(2000, 2, 29), + Duration(years=1, months=1, days=1), + date(2001, 3, 30)), + (date(2000, 2, 29), + Duration(years=1, days=1), + date(2001, 3, 1)), + (date(1996, 2, 29), + Duration(years=4, days=1), + date(2000, 3, 1)), + (date(2096, 2, 29), + Duration(years=4, days=1), + date(2100, 3, 1)), + (date(2000, 2, 1), + Duration(years=-1, months=-1, days=-1), + date(1998, 12, 31)), + (date(2000, 2, 29), + Duration(years=-1, months=-1, days=-1), + date(1999, 1, 28)), + (date(2001, 4, 1), + Duration(years=-1, months=-1, days=-1), + date(2000, 2, 29)), + (date(2000, 4, 1), + Duration(years=-1, months=-1, days=-1), + date(1999, 2, 28)), + (Duration(years=1, months=2), + Duration(years=0, months=0, days=1), + Duration(years=1, months=2, days=1)), + (Duration(years=-1, months=-1, days=-1), + date(2000, 4, 1), + date(1999, 2, 28)), + (Duration(years=1, months=1, weeks=5), + date(2000, 1, 30), + date(2001, 4, 4)), + (parse_duration("P1Y1M5W"), + date(2000, 1, 30), + date(2001, 4, 4)), + (parse_duration("P0.5Y"), + date(2000, 1, 30), + None), + (Duration(years=1, months=1, hours=3), + datetime(2000, 1, 30, 12, 15, 00), + datetime(2001, 2, 28, 15, 15, 00)), + (parse_duration("P1Y1MT3H"), + datetime(2000, 1, 30, 12, 15, 00), + datetime(2001, 2, 28, 15, 15, 00)), + (Duration(years=1, months=2), + timedelta(days=1), + Duration(years=1, months=2, days=1)), + (timedelta(days=1), + Duration(years=1, months=2), + Duration(years=1, months=2, days=1)), + (datetime(2008, 1, 1, 0, 2), + Duration(months=1), + datetime(2008, 2, 1, 0, 2)), + (datetime.strptime("200802", "%Y%M"), + parse_duration("P1M"), + datetime(2008, 2, 1, 0, 2)), + (datetime(2008, 2, 1), + Duration(months=1), + datetime(2008, 3, 1)), + (datetime.strptime("200802", "%Y%m"), + parse_duration("P1M"), + datetime(2008, 3, 1)), + # (date(2000, 1, 1), + # Duration(years=1.5), + # date(2001, 6, 1)), + # (date(2000, 1, 1), + # Duration(years=1, months=1.5), + # date(2001, 2, 14)), + ) class DurationTest(unittest.TestCase): @@ -340,11 +341,14 @@ class DurationTest(unittest.TestCase): Test conversion form Duration to timedelta. ''' dur = Duration(years=1, months=2, days=10) - self.assertEqual(dur.totimedelta(datetime(1998, 2, 25)), timedelta(434)) + self.assertEqual(dur.totimedelta(datetime(1998, 2, 25)), + timedelta(434)) # leap year has one day more in february - self.assertEqual(dur.totimedelta(datetime(2000, 2, 25)), timedelta(435)) + self.assertEqual(dur.totimedelta(datetime(2000, 2, 25)), + timedelta(435)) dur = Duration(months=2) - # march is longer than february, but april is shorter than march (cause only one day difference compared to 2) + # march is longer than february, but april is shorter than + # march (cause only one day difference compared to 2) self.assertEqual(dur.totimedelta(datetime(2000, 2, 25)), timedelta(60)) self.assertEqual(dur.totimedelta(datetime(2001, 2, 25)), timedelta(59)) self.assertEqual(dur.totimedelta(datetime(2001, 3, 25)), timedelta(61)) @@ -499,7 +503,8 @@ def test_suite(): Return a test suite containing all test defined above. ''' suite = unittest.TestSuite() - for durationstring, (expectation, format, altstr) in PARSE_TEST_CASES.items(): + for durationstring, (expectation, format, + altstr) in PARSE_TEST_CASES.items(): suite.addTest(create_parsetestcase(durationstring, expectation, format, altstr)) for testdata in MATH_TEST_CASES: @@ -511,6 +516,7 @@ def test_suite(): suite.addTest(unittest.TestLoader().loadTestsFromTestCase(DurationTest)) return suite + # load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() diff --git a/src/isodate/tests/test_pickle.py b/src/isodate/tests/test_pickle.py index 952c238..867bc40 100644 --- a/src/isodate/tests/test_pickle.py +++ b/src/isodate/tests/test_pickle.py @@ -27,6 +27,7 @@ def test_suite(): suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestPickle)) return suite + # load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() diff --git a/src/isodate/tests/test_strf.py b/src/isodate/tests/test_strf.py index c7f1c55..37a135b 100644 --- a/src/isodate/tests/test_strf.py +++ b/src/isodate/tests/test_strf.py @@ -42,9 +42,11 @@ TEST_CASES = ((datetime(2012, 12, 25, 13, 30, 0, 0, LOCAL), DT_EXT_COMPLETE, (datetime(1999, 12, 25, 13, 30, 0, 0, LOCAL), DT_EXT_COMPLETE, "1999-12-25T13:30:00+11:00"), # microseconds - (datetime(2012, 10, 12, 8, 29, 46, 69178), "%Y-%m-%dT%H:%M:%S.%f", + (datetime(2012, 10, 12, 8, 29, 46, 69178), + "%Y-%m-%dT%H:%M:%S.%f", "2012-10-12T08:29:46.069178"), - (datetime(2012, 10, 12, 8, 29, 46, 691780), "%Y-%m-%dT%H:%M:%S.%f", + (datetime(2012, 10, 12, 8, 29, 46, 691780), + "%Y-%m-%dT%H:%M:%S.%f", "2012-10-12T08:29:46.691780"), ) @@ -65,7 +67,8 @@ def create_testcase(dt, format, expectation): # local time zone mock function def localtime_mock(self, secs): """ - mock time.localtime so that it always returns a time_struct with tm_idst=1 + mock time.localtime so that it always returns a time_struct with + tm_idst=1 """ tt = self.ORIG['localtime'](secs) # befor 2000 everything is dst, after 2000 no dst. @@ -85,8 +88,9 @@ def create_testcase(dt, format, expectation): self.ORIG['DSTDIFF'] = tzinfo.DSTDIFF self.ORIG['localtime'] = time.localtime # ovveride all saved values with fixtures. - # calculate LOCAL TZ offset, so that this test runs in every time zone - tzinfo.STDOFFSET = timedelta(seconds=36000) # assume we are in +10:00 + # calculate LOCAL TZ offset, so that this test runs in + # every time zone + tzinfo.STDOFFSET = timedelta(seconds=36000) # assume LOC = +10:00 tzinfo.DSTOFFSET = timedelta(seconds=39600) # assume DST = +11:00 tzinfo.DSTDIFF = tzinfo.DSTOFFSET - tzinfo.STDOFFSET time.localtime = self.localtime_mock @@ -122,9 +126,10 @@ def test_suite(): suite.addTest(create_testcase(dt, format, expectation)) return suite + # load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() - + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff --git a/src/isodate/tests/test_time.py b/src/isodate/tests/test_time.py index cdce704..cc5ec08 100644 --- a/src/isodate/tests/test_time.py +++ b/src/isodate/tests/test_time.py @@ -54,36 +54,35 @@ TEST_CASES = [('232050', time(23, 20, 50), TIME_BAS_COMPLETE + TZ_BAS), ('23:20,8', time(23, 20, 48), None), ('23,3', time(23, 18), None), ('232030Z', time(23, 20, 30, tzinfo=UTC), - TIME_BAS_COMPLETE + TZ_BAS), + TIME_BAS_COMPLETE + TZ_BAS), ('2320Z', time(23, 20, tzinfo=UTC), TIME_BAS_MINUTE + TZ_BAS), ('23Z', time(23, tzinfo=UTC), TIME_HOUR + TZ_BAS), ('23:20:30Z', time(23, 20, 30, tzinfo=UTC), - TIME_EXT_COMPLETE + TZ_EXT), + TIME_EXT_COMPLETE + TZ_EXT), ('23:20Z', time(23, 20, tzinfo=UTC), TIME_EXT_MINUTE + TZ_EXT), ('152746+0100', time(15, 27, 46, - tzinfo=FixedOffset(1, 0, '+0100')), - TIME_BAS_COMPLETE + TZ_BAS), + tzinfo=FixedOffset(1, 0, '+0100')), TIME_BAS_COMPLETE + TZ_BAS), ('152746-0500', time(15, 27, 46, tzinfo=FixedOffset(-5, 0, '-0500')), - TIME_BAS_COMPLETE + TZ_BAS), + TIME_BAS_COMPLETE + TZ_BAS), ('152746+01', time(15, 27, 46, tzinfo=FixedOffset(1, 0, '+01:00')), - TIME_BAS_COMPLETE + TZ_HOUR), + TIME_BAS_COMPLETE + TZ_HOUR), ('152746-05', time(15, 27, 46, tzinfo=FixedOffset(-5, -0, '-05:00')), - TIME_BAS_COMPLETE + TZ_HOUR), + TIME_BAS_COMPLETE + TZ_HOUR), ('15:27:46+01:00', time(15, 27, 46, tzinfo=FixedOffset(1, 0, '+01:00')), - TIME_EXT_COMPLETE + TZ_EXT), + TIME_EXT_COMPLETE + TZ_EXT), ('15:27:46-05:00', time(15, 27, 46, tzinfo=FixedOffset(-5, -0, '-05:00')), - TIME_EXT_COMPLETE + TZ_EXT), + TIME_EXT_COMPLETE + TZ_EXT), ('15:27:46+01', time(15, 27, 46, tzinfo=FixedOffset(1, 0, '+01:00')), - TIME_EXT_COMPLETE + TZ_HOUR), + TIME_EXT_COMPLETE + TZ_HOUR), ('15:27:46-05', time(15, 27, 46, tzinfo=FixedOffset(-5, -0, '-05:00')), - TIME_EXT_COMPLETE + TZ_HOUR), + TIME_EXT_COMPLETE + TZ_HOUR), ('1:17:30', None, TIME_EXT_COMPLETE)] @@ -135,7 +134,8 @@ def test_suite(): suite.addTest(create_testcase(timestring, expectation, format)) return suite - # load_tests Protocol + +# load_tests Protocol def load_tests(loader, tests, pattern): return test_suite() diff --git a/src/isodate/tzinfo.py b/src/isodate/tzinfo.py index 820c88d..b41f058 100644 --- a/src/isodate/tzinfo.py +++ b/src/isodate/tzinfo.py @@ -9,6 +9,7 @@ import time ZERO = timedelta(0) # constant for zero time offset. + class Utc(tzinfo): '''UTC @@ -23,19 +24,22 @@ class Utc(tzinfo): def tzname(self, dt): ''' - Return the time zone name corresponding to the datetime object dt, as a string. + Return the time zone name corresponding to the datetime object dt, + as a string. ''' return "UTC" def dst(self, dt): ''' - Return the daylight saving time (DST) adjustment, in minutes east of UTC. + Return the daylight saving time (DST) adjustment, in minutes east + of UTC. ''' return ZERO UTC = Utc() # the default instance for UTC. + class FixedOffset(tzinfo): ''' A class building tzinfo objects for fixed-offset time zones. @@ -80,18 +84,19 @@ class FixedOffset(tzinfo): return "<FixedOffset %r>" % self.__name -STDOFFSET = timedelta(seconds = -time.timezone) +STDOFFSET = timedelta(seconds=-time.timezone) # locale time zone offset # calculate local daylight saving offset if any. if time.daylight: - DSTOFFSET = timedelta(seconds = -time.altzone) + DSTOFFSET = timedelta(seconds=-time.altzone) else: DSTOFFSET = STDOFFSET DSTDIFF = DSTOFFSET - STDOFFSET # difference between local time zone and local DST time zone + class LocalTimezone(tzinfo): """ A class capturing the platform's idea of local time. |