summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerhard Weis <g.weis@uq.edu.au>2021-12-13 08:06:56 +1000
committerGerhard Weis <g.weis@uq.edu.au>2021-12-13 08:06:56 +1000
commit07d1602048083415bc22dc72cff152c9c2e0e021 (patch)
tree6fc5875daf4002f4e8dd4b672da47083aad82b0c
parent4f36d7e6f6adee4c1ec719bb9beb035df4a7d76c (diff)
downloadisodate-07d1602048083415bc22dc72cff152c9c2e0e021.tar.gz
white space
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--src/isodate/__init__.py69
-rw-r--r--src/isodate/duration.py138
-rw-r--r--src/isodate/isodates.py163
-rw-r--r--src/isodate/isodatetime.py25
-rw-r--r--src/isodate/isoduration.py90
-rw-r--r--src/isodate/isoerror.py6
-rw-r--r--src/isodate/isostrf.py196
-rw-r--r--src/isodate/isotime.py116
-rw-r--r--src/isodate/isotzinfo.py62
-rw-r--r--src/isodate/tests/__init__.py40
-rw-r--r--src/isodate/tests/test_date.py104
-rw-r--r--src/isodate/tests/test_datetime.py198
-rw-r--r--src/isodate/tests/test_duration.py603
-rw-r--r--src/isodate/tests/test_pickle.py35
-rw-r--r--src/isodate/tests/test_strf.py95
-rw-r--r--src/isodate/tests/test_time.py153
-rw-r--r--src/isodate/tzinfo.py82
18 files changed, 1206 insertions, 971 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 763d597..c00dfd9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,6 +4,8 @@ repos:
rev: 3.9.1
hooks:
- id: flake8
+ args:
+ - "--max-line-length=88"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
diff --git a/src/isodate/__init__.py b/src/isodate/__init__.py
index 50862e1..f3897d8 100644
--- a/src/isodate/__init__.py
+++ b/src/isodate/__init__.py
@@ -24,12 +24,12 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
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.
-'''
+"""
from isodate.isodates import parse_date, date_isoformat
from isodate.isotime import parse_time, time_isoformat
from isodate.isodatetime import parse_datetime, datetime_isoformat
@@ -55,18 +55,53 @@ 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_YEAR',
- 'DATE_BAS_MONTH', 'DATE_EXT_MONTH',
- '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']
+__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_YEAR",
+ "DATE_BAS_MONTH",
+ "DATE_EXT_MONTH",
+ "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 4b83e45..f9495ea 100644
--- a/src/isodate/duration.py
+++ b/src/isodate/duration.py
@@ -24,21 +24,21 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This module defines a Duration class.
The class Duration allows to define durations in years and months and can be
used as limited replacement for timedelta objects.
-'''
+"""
from datetime import timedelta
from decimal import Decimal, ROUND_FLOOR
def fquotmod(val, low, high):
- '''
+ """
A divmod function with boundaries.
- '''
+ """
# 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.
@@ -52,9 +52,9 @@ def fquotmod(val, low, high):
def max_days_in_month(year, month):
- '''
+ """
Determines the number of days of a specific month in a specific year.
- '''
+ """
if month in (1, 3, 5, 7, 8, 10, 12):
return 31
if month in (4, 6, 9, 11):
@@ -65,7 +65,7 @@ def max_days_in_month(year, month):
class Duration(object):
- '''
+ """
A class which represents a duration.
The difference to datetime.timedelta is, that this class handles also
@@ -85,21 +85,32 @@ class Duration(object):
The algorithm to add a duration to a date is defined at
http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes
- '''
-
- def __init__(self, days=0, seconds=0, microseconds=0, milliseconds=0,
- minutes=0, hours=0, weeks=0, months=0, years=0):
- '''
+ """
+
+ def __init__(
+ self,
+ days=0,
+ seconds=0,
+ microseconds=0,
+ milliseconds=0,
+ minutes=0,
+ hours=0,
+ weeks=0,
+ months=0,
+ years=0,
+ ):
+ """
Initialise this Duration instance with the given parameters.
- '''
+ """
if not isinstance(months, Decimal):
months = Decimal(str(months))
if not isinstance(years, Decimal):
years = Decimal(str(years))
self.months = months
self.years = years
- self.tdelta = timedelta(days, seconds, microseconds, milliseconds,
- minutes, hours, weeks)
+ self.tdelta = timedelta(
+ days, seconds, microseconds, milliseconds, minutes, hours, weeks
+ )
def __getstate__(self):
return self.__dict__
@@ -108,40 +119,45 @@ class Duration(object):
self.__dict__.update(state)
def __getattr__(self, name):
- '''
+ """
Provide direct access to attributes of included timedelta instance.
- '''
+ """
return getattr(self.tdelta, name)
def __str__(self):
- '''
+ """
Return a string representation of this duration similar to timedelta.
- '''
+ """
params = []
if self.years:
- params.append('%d years' % self.years)
+ params.append("%d years" % self.years)
if self.months:
fmt = "%d months"
if self.months <= 1:
fmt = "%d month"
params.append(fmt % self.months)
params.append(str(self.tdelta))
- return ', '.join(params)
+ return ", ".join(params)
def __repr__(self):
- '''
+ """
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 __hash__(self):
- '''
+ """
Return a hash of this instance so that it can be used in, for
example, dicts and sets.
- '''
+ """
return hash((self.tdelta, self.months, self.years))
def __neg__(self):
@@ -155,23 +171,24 @@ class Duration(object):
return negduration
def __add__(self, other):
- '''
+ """
Durations can be added with Duration, timedelta, date and datetime
objects.
- '''
+ """
if isinstance(other, Duration):
- newduration = Duration(years=self.years + other.years,
- months=self.months + other.months)
+ newduration = Duration(
+ years=self.years + other.years, months=self.months + other.months
+ )
newduration.tdelta = self.tdelta + other.tdelta
return newduration
try:
# try anything that looks like a date or datetime
# 'other' has attributes year, month, day
# and relies on 'timedelta + other' being implemented
- 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
@@ -204,9 +221,7 @@ class Duration(object):
def __mul__(self, other):
if isinstance(other, int):
- newduration = Duration(
- years=self.years * other,
- months=self.months * other)
+ newduration = Duration(years=self.years * other, months=self.months * other)
newduration.tdelta = self.tdelta * other
return newduration
return NotImplemented
@@ -214,13 +229,14 @@ class Duration(object):
__rmul__ = __mul__
def __sub__(self, other):
- '''
+ """
It is possible to subtract Duration and timedelta objects from Duration
objects.
- '''
+ """
if isinstance(other, Duration):
- newduration = Duration(years=self.years - other.years,
- months=self.months - other.months)
+ newduration = Duration(
+ years=self.years - other.years, months=self.months - other.months
+ )
newduration.tdelta = self.tdelta - other.tdelta
return newduration
try:
@@ -234,7 +250,7 @@ class Duration(object):
return NotImplemented
def __rsub__(self, other):
- '''
+ """
It is possible to subtract Duration objecs from date, datetime and
timedelta objects.
@@ -246,7 +262,7 @@ class Duration(object):
the stdlib we can just do:
return -self + other
instead of all the current code
- '''
+ """
if isinstance(other, timedelta):
tmpdur = Duration()
tmpdur.tdelta = other
@@ -254,10 +270,10 @@ class Duration(object):
try:
# check if other behaves like a date/datetime object
# does it have year, month, day and replace?
- 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
@@ -276,14 +292,14 @@ class Duration(object):
return NotImplemented
def __eq__(self, other):
- '''
+ """
If the years, month part and the timedelta part are both equal, then
the two Durations are considered equal.
- '''
+ """
if isinstance(other, Duration):
- 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
# check if other con be compared against timedelta object
@@ -293,14 +309,14 @@ class Duration(object):
return False
def __ne__(self, other):
- '''
+ """
If the years, month part or the timedelta part is not equal, then
the two Durations are considered not equal.
- '''
+ """
if isinstance(other, Duration):
- 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
# check if other can be compared against timedelta object
@@ -310,12 +326,12 @@ class Duration(object):
return True
def totimedelta(self, start=None, end=None):
- '''
+ """
Convert this duration into a timedelta object.
This method requires a start datetime or end datetimem, but raises
an exception if both are given.
- '''
+ """
if start is None and end is None:
raise ValueError("start or end required")
if start is not None and end is not None:
diff --git a/src/isodate/isodates.py b/src/isodate/isodates.py
index aab5684..30ac8cd 100644
--- a/src/isodate/isodates.py
+++ b/src/isodate/isodates.py
@@ -24,14 +24,14 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This modules provides a method to parse an ISO 8601:2004 date string to a
python datetime.date instance.
It supports all basic, extended and expanded formats as described in the ISO
standard. The only limitations it has, are given by the Python datetime.date
implementation, which does not support dates before 0001-01-01.
-'''
+"""
import re
from datetime import date, timedelta
@@ -46,7 +46,7 @@ DATE_REGEX_CACHE = {}
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.
@@ -56,7 +56,7 @@ def build_date_regexps(yeardigits=4, expanded=False):
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,
the expanded parameter needs to be set to True.
- '''
+ """
if yeardigits != 4:
expanded = True
if (yeardigits, expanded) not in DATE_REGEX_CACHE:
@@ -69,67 +69,98 @@ def build_date_regexps(yeardigits=4, expanded=False):
sign = 0
# 1. complete dates:
# YYYY-MM-DD or +- YYYYYY-MM-DD... extended 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})"
- % (sign, yeardigits)))
+ 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})" % (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})"
- % (sign, yeardigits)))
+ 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})" % (sign, yeardigits)
+ )
+ )
# 2. complete week dates:
# YYYY-Www-D or +-YYYYYY-Www-D ... extended week date
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"-W(?P<week>[0-9]{2})-(?P<day>[0-9]{1})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
+ r"-W(?P<week>[0-9]{2})-(?P<day>[0-9]{1})" % (sign, yeardigits)
+ )
+ )
# YYYYWwwD or +-YYYYYYWwwD ... basic week date
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})W"
- r"(?P<week>[0-9]{2})(?P<day>[0-9]{1})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})W"
+ r"(?P<week>[0-9]{2})(?P<day>[0-9]{1})" % (sign, yeardigits)
+ )
+ )
# 3. ordinal dates:
# YYYY-DDD or +-YYYYYY-DDD ... extended format
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"-(?P<day>[0-9]{3})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
+ r"-(?P<day>[0-9]{3})" % (sign, yeardigits)
+ )
+ )
# YYYYDDD or +-YYYYYYDDD ... basic format
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"(?P<day>[0-9]{3})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
+ r"(?P<day>[0-9]{3})" % (sign, yeardigits)
+ )
+ )
# 4. week dates:
# YYYY-Www or +-YYYYYY-Www ... extended reduced accuracy week date
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"-W(?P<week>[0-9]{2})"
- % (sign, yeardigits)))
+ 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
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})W"
- r"(?P<week>[0-9]{2})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})W"
+ r"(?P<week>[0-9]{2})" % (sign, yeardigits)
+ )
+ )
# 5. month dates:
# YYY-MM or +-YYYYYY-MM ... reduced accuracy specific month
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"-(?P<month>[0-9]{2})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
+ r"-(?P<month>[0-9]{2})" % (sign, yeardigits)
+ )
+ )
# YYYMM or +-YYYYYYMM ... basic incomplete month date format
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- r"(?P<month>[0-9]{2})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
+ r"(?P<month>[0-9]{2})" % (sign, yeardigits)
+ )
+ )
# 6. year dates:
# YYYY or +-YYYYYY ... reduced accuracy specific year
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})"
- % (sign, yeardigits)))
+ cache_entry.append(
+ re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" % (sign, yeardigits))
+ )
# 7. century dates:
# YY or +-YYYY ... reduced accuracy specific century
- cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}"
- r"(?P<century>[0-9]{%d})"
- % (sign, yeardigits - 2)))
+ cache_entry.append(
+ re.compile(
+ r"(?P<sign>[+-]){%d}" r"(?P<century>[0-9]{%d})" % (sign, yeardigits - 2)
+ )
+ )
DATE_REGEX_CACHE[(yeardigits, expanded)] = cache_entry
return DATE_REGEX_CACHE[(yeardigits, expanded)]
-def parse_date(
- datestring,
- yeardigits=4, expanded=False, defaultmonth=1, defaultday=1):
- '''
+def parse_date(datestring, yeardigits=4, expanded=False, defaultmonth=1, defaultday=1):
+ """
Parse an ISO 8601 date string into a datetime.date object.
As the datetime.date implementation is limited to dates starting from
@@ -162,7 +193,7 @@ def parse_date(
@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
- '''
+ """
if yeardigits != 4:
expanded = True
isodates = build_date_regexps(yeardigits, expanded)
@@ -172,42 +203,44 @@ def parse_date(
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
- if 'century' in groups:
+ sign = (groups["sign"] == "-" and -1) or 1
+ if "century" in groups:
return date(
- sign * (int(groups['century']) * 100 + 1),
- defaultmonth, defaultday)
- if 'month' not in groups: # weekdate or ordinal date
- ret = date(sign * int(groups['year']), 1, 1)
- if 'week' in groups:
+ sign * (int(groups["century"]) * 100 + 1), defaultmonth, defaultday
+ )
+ if "month" not in groups: # weekdate or ordinal date
+ ret = date(sign * int(groups["year"]), 1, 1)
+ if "week" in groups:
isotuple = ret.isocalendar()
- if 'day' in groups:
- days = int(groups['day'] or 1)
+ if "day" in groups:
+ days = int(groups["day"] or 1)
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(days=int(groups['day']) - 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(days=int(groups["day"]) - 1)
else: # year date
return ret.replace(month=defaultmonth, day=defaultday)
# year-, month-, or complete date
- if 'day' not in groups or groups['day'] is None:
+ if "day" not in groups or groups["day"] is None:
day = defaultday
else:
- day = int(groups['day'])
- return date(sign * int(groups['year']),
- int(groups['month']) or defaultmonth, day)
- raise ISO8601Error('Unrecognised ISO 8601 date format: %r' % datestring)
+ day = int(groups["day"])
+ return date(
+ sign * int(groups["year"]), int(groups["month"]) or defaultmonth, day
+ )
+ raise ISO8601Error("Unrecognised ISO 8601 date format: %r" % datestring)
def date_isoformat(tdate, format=DATE_EXT_COMPLETE, yeardigits=4):
- '''
+ """
Format date strings.
This method is just a wrapper around isodate.isostrf.strftime and uses
Date-Extended-Complete as default format.
- '''
+ """
return strftime(tdate, format, yeardigits)
diff --git a/src/isodate/isodatetime.py b/src/isodate/isodatetime.py
index 9a5fce0..c4d37f9 100644
--- a/src/isodate/isodatetime.py
+++ b/src/isodate/isodatetime.py
@@ -24,12 +24,12 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This module defines a method to parse an ISO 8601:2004 date time string.
For this job it uses the parse_date and parse_time methods defined in date
and time module.
-'''
+"""
from datetime import datetime
from isodate.isostrf import strftime
@@ -40,29 +40,32 @@ 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.
- '''
+ """
try:
- datestring, timestring = datetimestring.split('T')
+ datestring, timestring = datetimestring.split("T")
except ValueError:
- raise ISO8601Error("ISO 8601 time designator 'T' missing. Unable to"
- " parse datetime string %r" % datetimestring)
+ raise ISO8601Error(
+ "ISO 8601 time designator 'T' missing. Unable to"
+ " parse datetime string %r" % datetimestring
+ )
tmpdate = parse_date(datestring)
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.
This method is just a wrapper around isodate.isostrf.strftime and uses
Extended-Complete as default format.
- '''
+ """
return strftime(tdt, format)
diff --git a/src/isodate/isoduration.py b/src/isodate/isoduration.py
index 88829f7..bbfa7a4 100644
--- a/src/isodate/isoduration.py
+++ b/src/isodate/isoduration.py
@@ -24,18 +24,16 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This module provides an ISO 8601:2004 duration parser.
It also provides a wrapper to strftime. This wrapper makes it easier to
format timedelta or Duration instances as ISO conforming strings.
-'''
+"""
from datetime import timedelta
from decimal import Decimal
import re
-from six import string_types
-
from isodate.duration import Duration
from isodate.isoerror import ISO8601Error
from isodate.isodatetime import parse_datetime
@@ -50,7 +48,8 @@ ISO8601_PERIOD_REGEX = re.compile(
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)?)?$")
+ r"(?P<seconds>[0-9]+([,.][0-9]+)?S)?)?$"
+)
# regular expression to parse ISO duartion strings.
@@ -82,7 +81,7 @@ def parse_duration(datestring):
The alternative format does not support durations with years, months or
days set to 0.
"""
- if not isinstance(datestring, string_types):
+ if not isinstance(datestring, str):
raise TypeError("Expecting a string %r" % datestring)
match = ISO8601_PERIOD_REGEX.match(datestring)
if not match:
@@ -91,61 +90,82 @@ def parse_duration(datestring):
durdt = parse_datetime(datestring[1:])
if durdt.year != 0 or durdt.month != 0:
# create Duration
- ret = Duration(days=durdt.day, seconds=durdt.second,
- microseconds=durdt.microsecond,
- minutes=durdt.minute, hours=durdt.hour,
- months=durdt.month, years=durdt.year)
+ ret = Duration(
+ days=durdt.day,
+ seconds=durdt.second,
+ microseconds=durdt.microsecond,
+ minutes=durdt.minute,
+ hours=durdt.hour,
+ months=durdt.month,
+ years=durdt.year,
+ )
else: # FIXME: currently not possible in alternative format
# create timedelta
- ret = timedelta(days=durdt.day, seconds=durdt.second,
- microseconds=durdt.microsecond,
- minutes=durdt.minute, hours=durdt.hour)
+ ret = timedelta(
+ days=durdt.day,
+ seconds=durdt.second,
+ microseconds=durdt.microsecond,
+ minutes=durdt.minute,
+ hours=durdt.hour,
+ )
return ret
raise ISO8601Error("Unable to parse duration string %r" % datestring)
groups = match.groupdict()
for key, val in groups.items():
- if key not in ('separator', 'sign'):
+ if key not in ("separator", "sign"):
if val is None:
groups[key] = "0n"
# print groups[key]
- if key in ('years', 'months'):
- groups[key] = Decimal(groups[key][:-1].replace(',', '.'))
+ 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.
- groups[key] = float(groups[key][:-1].replace(',', '.'))
+ groups[key] = float(groups[key][:-1].replace(",", "."))
if groups["years"] == 0 and groups["months"] == 0:
- ret = timedelta(days=groups["days"], hours=groups["hours"],
- minutes=groups["minutes"], seconds=groups["seconds"],
- weeks=groups["weeks"])
- if groups["sign"] == '-':
+ ret = timedelta(
+ days=groups["days"],
+ hours=groups["hours"],
+ minutes=groups["minutes"],
+ seconds=groups["seconds"],
+ weeks=groups["weeks"],
+ )
+ if groups["sign"] == "-":
ret = timedelta(0) - ret
else:
- ret = Duration(years=groups["years"], months=groups["months"],
- days=groups["days"], hours=groups["hours"],
- minutes=groups["minutes"], seconds=groups["seconds"],
- weeks=groups["weeks"])
- if groups["sign"] == '-':
+ ret = Duration(
+ years=groups["years"],
+ months=groups["months"],
+ days=groups["days"],
+ hours=groups["hours"],
+ minutes=groups["minutes"],
+ seconds=groups["seconds"],
+ weeks=groups["weeks"],
+ )
+ if groups["sign"] == "-":
ret = Duration(0) - ret
return ret
def duration_isoformat(tduration, format=D_DEFAULT):
- '''
+ """
Format duration strings.
This method is just a wrapper around isodate.isostrf.strftime and uses
P%P (D_DEFAULT) as default format.
- '''
+ """
# 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))))):
- ret = '-'
+ 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 = ''
+ ret = ""
ret += strftime(tduration, format)
return ret
diff --git a/src/isodate/isoerror.py b/src/isodate/isoerror.py
index e7b211b..0c60b2d 100644
--- a/src/isodate/isoerror.py
+++ b/src/isodate/isoerror.py
@@ -24,10 +24,10 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This module defines all exception classes in the whole package.
-'''
+"""
class ISO8601Error(ValueError):
- '''Raised when the given ISO string can not be parsed.'''
+ """Raised when the given ISO string can not be parsed."""
diff --git a/src/isodate/isostrf.py b/src/isodate/isostrf.py
index 642044b..c57899f 100644
--- a/src/isodate/isostrf.py
+++ b/src/isodate/isostrf.py
@@ -40,153 +40,153 @@ from isodate.duration import Duration
from isodate.isotzinfo import tz_isoformat
# Date specific format strings
-DATE_BAS_COMPLETE = '%Y%m%d'
-DATE_EXT_COMPLETE = '%Y-%m-%d'
-DATE_BAS_WEEK_COMPLETE = '%YW%W%w'
-DATE_EXT_WEEK_COMPLETE = '%Y-W%W-%w'
-DATE_BAS_ORD_COMPLETE = '%Y%j'
-DATE_EXT_ORD_COMPLETE = '%Y-%j'
-DATE_BAS_WEEK = '%YW%W'
-DATE_EXT_WEEK = '%Y-W%W'
-DATE_BAS_MONTH = '%Y%m'
-DATE_EXT_MONTH = '%Y-%m'
-DATE_YEAR = '%Y'
-DATE_CENTURY = '%C'
+DATE_BAS_COMPLETE = "%Y%m%d"
+DATE_EXT_COMPLETE = "%Y-%m-%d"
+DATE_BAS_WEEK_COMPLETE = "%YW%W%w"
+DATE_EXT_WEEK_COMPLETE = "%Y-W%W-%w"
+DATE_BAS_ORD_COMPLETE = "%Y%j"
+DATE_EXT_ORD_COMPLETE = "%Y-%j"
+DATE_BAS_WEEK = "%YW%W"
+DATE_EXT_WEEK = "%Y-W%W"
+DATE_BAS_MONTH = "%Y%m"
+DATE_EXT_MONTH = "%Y-%m"
+DATE_YEAR = "%Y"
+DATE_CENTURY = "%C"
# Time specific format strings
-TIME_BAS_COMPLETE = '%H%M%S'
-TIME_EXT_COMPLETE = '%H:%M:%S'
-TIME_BAS_MINUTE = '%H%M'
-TIME_EXT_MINUTE = '%H:%M'
-TIME_HOUR = '%H'
+TIME_BAS_COMPLETE = "%H%M%S"
+TIME_EXT_COMPLETE = "%H:%M:%S"
+TIME_BAS_MINUTE = "%H%M"
+TIME_EXT_MINUTE = "%H:%M"
+TIME_HOUR = "%H"
# Time zone formats
-TZ_BAS = '%z'
-TZ_EXT = '%Z'
-TZ_HOUR = '%h'
+TZ_BAS = "%z"
+TZ_EXT = "%Z"
+TZ_HOUR = "%h"
# DateTime formats
-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_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
# Duration formts
-D_DEFAULT = 'P%P'
-D_WEEK = 'P%p'
-D_ALT_EXT = 'P' + DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE
-D_ALT_BAS = 'P' + DATE_BAS_COMPLETE + 'T' + TIME_BAS_COMPLETE
-D_ALT_EXT_ORD = 'P' + DATE_EXT_ORD_COMPLETE + 'T' + TIME_EXT_COMPLETE
-D_ALT_BAS_ORD = 'P' + DATE_BAS_ORD_COMPLETE + 'T' + TIME_BAS_COMPLETE
-
-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),
- '%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)),
- '%h': lambda tdt, yds: tz_isoformat(tdt, '%h'),
- '%Z': lambda tdt, yds: tz_isoformat(tdt, '%Z'),
- '%z': lambda tdt, yds: tz_isoformat(tdt, '%z'),
- '%%': lambda tdt, yds: '%'}
-
-STRF_D_MAP = {'%d': lambda tdt, yds: '%02d' % tdt.days,
- '%f': lambda tdt, yds: '%06d' % tdt.microseconds,
- '%H': lambda tdt, yds: '%02d' % (tdt.seconds / 60 / 60),
- '%m': lambda tdt, yds: '%02d' % tdt.months,
- '%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)),
- '%%': lambda tdt, yds: '%'}
+D_DEFAULT = "P%P"
+D_WEEK = "P%p"
+D_ALT_EXT = "P" + DATE_EXT_COMPLETE + "T" + TIME_EXT_COMPLETE
+D_ALT_BAS = "P" + DATE_BAS_COMPLETE + "T" + TIME_BAS_COMPLETE
+D_ALT_EXT_ORD = "P" + DATE_EXT_ORD_COMPLETE + "T" + TIME_EXT_COMPLETE
+D_ALT_BAS_ORD = "P" + DATE_BAS_ORD_COMPLETE + "T" + TIME_BAS_COMPLETE
+
+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),
+ "%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)),
+ "%h": lambda tdt, yds: tz_isoformat(tdt, "%h"),
+ "%Z": lambda tdt, yds: tz_isoformat(tdt, "%Z"),
+ "%z": lambda tdt, yds: tz_isoformat(tdt, "%z"),
+ "%%": lambda tdt, yds: "%",
+}
+
+STRF_D_MAP = {
+ "%d": lambda tdt, yds: "%02d" % tdt.days,
+ "%f": lambda tdt, yds: "%06d" % tdt.microseconds,
+ "%H": lambda tdt, yds: "%02d" % (tdt.seconds / 60 / 60),
+ "%m": lambda tdt, yds: "%02d" % tdt.months,
+ "%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)),
+ "%%": lambda tdt, yds: "%",
+}
def _strfduration(tdt, format, yeardigits=4):
- '''
+ """
this is the work method for timedelta and Duration instances.
see strftime for more details.
- '''
+ """
+
def repl(match):
- '''
+ """
lookup format command and return corresponding replacement.
- '''
+ """
if match.group(0) in STRF_D_MAP:
return STRF_D_MAP[match.group(0)](tdt, yeardigits)
- elif match.group(0) == '%P':
+ elif match.group(0) == "%P":
ret = []
if isinstance(tdt, Duration):
if tdt.years:
- ret.append('%sY' % abs(tdt.years))
+ ret.append("%sY" % abs(tdt.years))
if tdt.months:
- ret.append('%sM' % abs(tdt.months))
- usecs = abs((tdt.days * 24 * 60 * 60 + tdt.seconds) * 1000000 +
- tdt.microseconds)
+ ret.append("%sM" % abs(tdt.months))
+ usecs = abs(
+ (tdt.days * 24 * 60 * 60 + tdt.seconds) * 1000000 + tdt.microseconds
+ )
seconds, usecs = divmod(usecs, 1000000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
if days:
- ret.append('%sD' % days)
+ ret.append("%sD" % days)
if hours or minutes or seconds or usecs:
- ret.append('T')
+ ret.append("T")
if hours:
- ret.append('%sH' % hours)
+ ret.append("%sH" % hours)
if minutes:
- ret.append('%sM' % minutes)
+ ret.append("%sM" % minutes)
if seconds or usecs:
if usecs:
- ret.append(("%d.%06d" % (seconds, usecs)).rstrip('0'))
+ ret.append(("%d.%06d" % (seconds, usecs)).rstrip("0"))
else:
ret.append("%d" % seconds)
- ret.append('S')
+ ret.append("S")
# at least one component has to be there.
- return ret and ''.join(ret) or '0D'
- elif match.group(0) == '%p':
- return str(abs(tdt.days // 7)) + 'W'
+ return ret and "".join(ret) or "0D"
+ elif match.group(0) == "%p":
+ return str(abs(tdt.days // 7)) + "W"
return match.group(0)
- return re.sub('%d|%f|%H|%m|%M|%S|%W|%Y|%C|%%|%P|%p', repl,
- format)
+
+ return re.sub("%d|%f|%H|%m|%M|%S|%W|%Y|%C|%%|%P|%p", repl, format)
def _strfdt(tdt, format, yeardigits=4):
- '''
+ """
this is the work method for time and date instances.
see strftime for more details.
- '''
+ """
+
def repl(match):
- '''
+ """
lookup format command and return corresponding replacement.
- '''
+ """
if match.group(0) in STRF_DT_MAP:
return STRF_DT_MAP[match.group(0)](tdt, yeardigits)
return match.group(0)
- return re.sub('%d|%f|%H|%j|%m|%M|%S|%w|%W|%Y|%C|%z|%Z|%h|%%', repl,
- format)
+
+ return re.sub("%d|%f|%H|%j|%m|%M|%S|%w|%W|%Y|%C|%z|%Z|%h|%%", repl, format)
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)
@@ -208,7 +208,7 @@ def strftime(tdt, format, yeardigits=4):
%p ISO8601 duration format in weeks.
%% A literal '%' character.
- '''
+ """
if isinstance(tdt, (timedelta, Duration)):
return _strfduration(tdt, format, yeardigits)
return _strfdt(tdt, format, yeardigits)
diff --git a/src/isodate/isotime.py b/src/isodate/isotime.py
index 113d34b..189fc06 100644
--- a/src/isodate/isotime.py
+++ b/src/isodate/isotime.py
@@ -24,13 +24,13 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
This modules provides a method to parse an ISO 8601:2004 time string to a
Python datetime.time instance.
It supports all basic and extended formats including time zone specifications
as described in the ISO standard.
-'''
+"""
import re
from decimal import Decimal
from datetime import time
@@ -44,12 +44,12 @@ TIME_REGEX_CACHE = []
def build_time_regexps():
- '''
+ """
Build regular expressions to parse ISO time string.
The regular expressions are compiled and stored in TIME_REGEX_CACHE
for later reuse.
- '''
+ """
if not TIME_REGEX_CACHE:
# ISO 8601 time representations allow decimal fractions on least
# significant time component. Command and Full Stop are both valid
@@ -69,32 +69,49 @@ def build_time_regexps():
# isotzinfo.TZ_REGEX
# 1. complete time:
# hh:mm:ss.ss ... extended format
- TIME_REGEX_CACHE.append(re.compile(r"T?(?P<hour>[0-9]{2}):"
- r"(?P<minute>[0-9]{2}):"
- r"(?P<second>[0-9]{2}"
- r"([,.][0-9]+)?)" + TZ_REGEX))
+ TIME_REGEX_CACHE.append(
+ re.compile(
+ r"T?(?P<hour>[0-9]{2}):"
+ r"(?P<minute>[0-9]{2}):"
+ r"(?P<second>[0-9]{2}"
+ r"([,.][0-9]+)?)" + TZ_REGEX
+ )
+ )
# hhmmss.ss ... basic format
- TIME_REGEX_CACHE.append(re.compile(r"T?(?P<hour>[0-9]{2})"
- r"(?P<minute>[0-9]{2})"
- r"(?P<second>[0-9]{2}"
- r"([,.][0-9]+)?)" + TZ_REGEX))
+ TIME_REGEX_CACHE.append(
+ re.compile(
+ r"T?(?P<hour>[0-9]{2})"
+ r"(?P<minute>[0-9]{2})"
+ r"(?P<second>[0-9]{2}"
+ r"([,.][0-9]+)?)" + TZ_REGEX
+ )
+ )
# 2. reduced accuracy:
# hh:mm.mm ... extended format
- TIME_REGEX_CACHE.append(re.compile(r"T?(?P<hour>[0-9]{2}):"
- r"(?P<minute>[0-9]{2}"
- r"([,.][0-9]+)?)" + TZ_REGEX))
+ TIME_REGEX_CACHE.append(
+ re.compile(
+ r"T?(?P<hour>[0-9]{2}):"
+ r"(?P<minute>[0-9]{2}"
+ r"([,.][0-9]+)?)" + TZ_REGEX
+ )
+ )
# hhmm.mm ... basic format
- TIME_REGEX_CACHE.append(re.compile(r"T?(?P<hour>[0-9]{2})"
- r"(?P<minute>[0-9]{2}"
- r"([,.][0-9]+)?)" + TZ_REGEX))
+ TIME_REGEX_CACHE.append(
+ re.compile(
+ r"T?(?P<hour>[0-9]{2})"
+ r"(?P<minute>[0-9]{2}"
+ r"([,.][0-9]+)?)" + TZ_REGEX
+ )
+ )
# hh.hh ... basic format
- TIME_REGEX_CACHE.append(re.compile(r"T?(?P<hour>[0-9]{2}"
- r"([,.][0-9]+)?)" + TZ_REGEX))
+ TIME_REGEX_CACHE.append(
+ re.compile(r"T?(?P<hour>[0-9]{2}" r"([,.][0-9]+)?)" + TZ_REGEX)
+ )
return TIME_REGEX_CACHE
def parse_time(timestring):
- '''
+ """
Parses ISO 8601 times into datetime.time objects.
Following ISO 8601 formats are supported:
@@ -110,7 +127,7 @@ def parse_time(timestring):
+-hhmm basic hours and minutes
+-hh:mm extended hours and minutes
+-hh hours
- '''
+ """
isotimes = build_time_regexps()
for pattern in isotimes:
match = pattern.match(timestring)
@@ -118,41 +135,58 @@ def parse_time(timestring):
groups = match.groupdict()
for key, value in groups.items():
if value is not None:
- groups[key] = value.replace(',', '.')
- tzinfo = build_tzinfo(groups['tzname'], groups['tzsign'],
- int(groups['tzhour'] or 0),
- int(groups['tzmin'] or 0))
- if 'second' in groups:
+ groups[key] = value.replace(",", ".")
+ tzinfo = build_tzinfo(
+ groups["tzname"],
+ groups["tzsign"],
+ int(groups["tzhour"] or 0),
+ int(groups["tzmin"] or 0),
+ )
+ if "second" in groups:
# round to microseconds if fractional seconds are more precise
- second = Decimal(groups['second']).quantize(Decimal('.000001'))
+ second = Decimal(groups["second"]).quantize(Decimal(".000001"))
microsecond = (second - int(second)) * int(1e6)
# int(...) ... no rounding
# to_integral() ... rounding
- return time(int(groups['hour']), int(groups['minute']),
- int(second), int(microsecond.to_integral()),
- tzinfo)
- if 'minute' in groups:
- minute = Decimal(groups['minute'])
+ return time(
+ int(groups["hour"]),
+ int(groups["minute"]),
+ int(second),
+ int(microsecond.to_integral()),
+ tzinfo,
+ )
+ if "minute" in groups:
+ minute = Decimal(groups["minute"])
second = (minute - int(minute)) * 60
microsecond = (second - int(second)) * int(1e6)
- return time(int(groups['hour']), int(minute), int(second),
- int(microsecond.to_integral()), tzinfo)
+ return time(
+ int(groups["hour"]),
+ int(minute),
+ int(second),
+ int(microsecond.to_integral()),
+ tzinfo,
+ )
else:
microsecond, second, minute = 0, 0, 0
- hour = Decimal(groups['hour'])
+ hour = Decimal(groups["hour"])
minute = (hour - int(hour)) * 60
second = (minute - int(minute)) * 60
microsecond = (second - int(second)) * int(1e6)
- return time(int(hour), int(minute), int(second),
- int(microsecond.to_integral()), tzinfo)
- raise ISO8601Error('Unrecognised ISO 8601 time format: %r' % timestring)
+ return time(
+ int(hour),
+ int(minute),
+ int(second),
+ int(microsecond.to_integral()),
+ tzinfo,
+ )
+ raise ISO8601Error("Unrecognised ISO 8601 time format: %r" % timestring)
def time_isoformat(ttime, format=TIME_EXT_COMPLETE + TZ_EXT):
- '''
+ """
Format time strings.
This method is just a wrapper around isodate.isostrf.strftime and uses
Time-Extended-Complete with extended time zone as default format.
- '''
+ """
return strftime(ttime, format)
diff --git a/src/isodate/isotzinfo.py b/src/isodate/isotzinfo.py
index a805ebe..d096dd3 100644
--- a/src/isodate/isotzinfo.py
+++ b/src/isodate/isotzinfo.py
@@ -24,41 +24,42 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
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.
-'''
+"""
import re
from isodate.isoerror import ISO8601Error
from isodate.tzinfo import UTC, FixedOffset, ZERO
-TZ_REGEX = r"(?P<tzname>(Z|(?P<tzsign>[+-])"\
- r"(?P<tzhour>[0-9]{2})(:?(?P<tzmin>[0-9]{2}))?)?)"
+TZ_REGEX = (
+ r"(?P<tzname>(Z|(?P<tzsign>[+-])" r"(?P<tzhour>[0-9]{2})(:?(?P<tzmin>[0-9]{2}))?)?)"
+)
TZ_RE = re.compile(TZ_REGEX)
-def build_tzinfo(tzname, tzsign='+', tzhour=0, tzmin=0):
- '''
+def build_tzinfo(tzname, tzsign="+", tzhour=0, tzmin=0):
+ """
create a tzinfo instance according to given parameters.
tzname:
'Z' ... return UTC
'' | None ... return None
other ... return FixedOffset
- '''
- if tzname is None or tzname == '':
+ """
+ if tzname is None or tzname == "":
return None
- if tzname == 'Z':
+ if tzname == "Z":
return UTC
- tzsign = ((tzsign == '-') and -1) or 1
+ 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:
@@ -67,18 +68,21 @@ def parse_tzinfo(tzstring):
+-hhmm basic hours and minutes
+-hh:mm extended hours and minutes
+-hh hours
- '''
+ """
match = TZ_RE.match(tzstring)
if match:
groups = match.groupdict()
- 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)
+ 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'):
- '''
+def tz_isoformat(dt, format="%Z"):
+ """
return time zone offset ISO 8601 formatted.
The various ISO formats can be chosen with the format parameter.
@@ -89,24 +93,24 @@ def tz_isoformat(dt, format='%Z'):
%h ... +-HH
%z ... +-HHMM
%Z ... +-HH:MM
- '''
+ """
tzinfo = dt.tzinfo
if (tzinfo is None) or (tzinfo.utcoffset(dt) is None):
- return ''
+ return ""
if tzinfo.utcoffset(dt) == ZERO and tzinfo.dst(dt) == ZERO:
- return 'Z'
+ return "Z"
tdelta = tzinfo.utcoffset(dt)
seconds = tdelta.days * 24 * 60 * 60 + tdelta.seconds
- sign = ((seconds < 0) and '-') or '+'
+ sign = ((seconds < 0) and "-") or "+"
seconds = abs(seconds)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
if hours > 99:
- raise OverflowError('can not handle differences > 99 hours')
- if format == '%Z':
- return '%s%02d:%02d' % (sign, hours, minutes)
- elif format == '%z':
- return '%s%02d%02d' % (sign, hours, minutes)
- elif format == '%h':
- return '%s%02d' % (sign, hours)
+ raise OverflowError("can not handle differences > 99 hours")
+ if format == "%Z":
+ return "%s%02d:%02d" % (sign, hours, minutes)
+ elif format == "%z":
+ return "%s%02d%02d" % (sign, hours, minutes)
+ elif format == "%h":
+ return "%s%02d" % (sign, hours)
raise ValueError('unknown format string "%s"' % format)
diff --git a/src/isodate/tests/__init__.py b/src/isodate/tests/__init__.py
index b1d46bd..421de3a 100644
--- a/src/isodate/tests/__init__.py
+++ b/src/isodate/tests/__init__.py
@@ -24,28 +24,36 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Collect all test suites into one TestSuite instance.
-'''
+"""
import unittest
-from isodate.tests import (test_date, test_time, test_datetime, test_duration,
- test_strf, test_pickle)
+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.
- '''
- return unittest.TestSuite([
- test_date.test_suite(),
- test_time.test_suite(),
- test_datetime.test_suite(),
- test_duration.test_suite(),
- test_strf.test_suite(),
- test_pickle.test_suite(),
- ])
+ """
+ return unittest.TestSuite(
+ [
+ test_date.test_suite(),
+ test_time.test_suite(),
+ test_datetime.test_suite(),
+ test_duration.test_suite(),
+ test_strf.test_suite(),
+ test_pickle.test_suite(),
+ ]
+ )
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
+if __name__ == "__main__":
+ unittest.main(defaultTest="test_suite")
diff --git a/src/isodate/tests/test_date.py b/src/isodate/tests/test_date.py
index 6ee89cb..eb1bfe0 100644
--- a/src/isodate/tests/test_date.py
+++ b/src/isodate/tests/test_date.py
@@ -24,9 +24,9 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Test cases for the isodate module.
-'''
+"""
import unittest
from datetime import date
from isodate import parse_date, ISO8601Error, date_isoformat
@@ -41,85 +41,89 @@ from isodate import DATE_EXT_WEEK, DATE_EXT_WEEK_COMPLETE
# result from the parse_date method. A result of None means an ISO8601Error
# is expected. The test cases are grouped into dates with 4 digit years
# and 6 digit years.
-TEST_CASES = {4: [('19', date(1901, 1, 1), DATE_CENTURY),
- ('1985', date(1985, 1, 1), DATE_YEAR),
- ('1985-04', date(1985, 4, 1), DATE_EXT_MONTH),
- ('198504', date(1985, 4, 1), DATE_BAS_MONTH),
- ('1985-04-12', date(1985, 4, 12), DATE_EXT_COMPLETE),
- ('19850412', date(1985, 4, 12), DATE_BAS_COMPLETE),
- ('1985102', date(1985, 4, 12), DATE_BAS_ORD_COMPLETE),
- ('1985-102', date(1985, 4, 12), DATE_EXT_ORD_COMPLETE),
- ('1985W155', date(1985, 4, 12), DATE_BAS_WEEK_COMPLETE),
- ('1985-W15-5', date(1985, 4, 12), DATE_EXT_WEEK_COMPLETE),
- ('1985W15', date(1985, 4, 8), DATE_BAS_WEEK),
- ('1985-W15', date(1985, 4, 8), DATE_EXT_WEEK),
- ('1989-W15', date(1989, 4, 10), DATE_EXT_WEEK),
- ('1989-W15-5', date(1989, 4, 14), DATE_EXT_WEEK_COMPLETE),
- ('1-W1-1', None, DATE_BAS_WEEK_COMPLETE)],
- 6: [('+0019', date(1901, 1, 1), DATE_CENTURY),
- ('+001985', date(1985, 1, 1), DATE_YEAR),
- ('+001985-04', date(1985, 4, 1), DATE_EXT_MONTH),
- ('+001985-04-12', date(1985, 4, 12), DATE_EXT_COMPLETE),
- ('+0019850412', date(1985, 4, 12), DATE_BAS_COMPLETE),
- ('+001985102', date(1985, 4, 12), DATE_BAS_ORD_COMPLETE),
- ('+001985-102', date(1985, 4, 12), DATE_EXT_ORD_COMPLETE),
- ('+001985W155', date(1985, 4, 12), DATE_BAS_WEEK_COMPLETE),
- ('+001985-W15-5', date(1985, 4, 12), DATE_EXT_WEEK_COMPLETE),
- ('+001985W15', date(1985, 4, 8), DATE_BAS_WEEK),
- ('+001985-W15', date(1985, 4, 8), DATE_EXT_WEEK)]}
+TEST_CASES = {
+ 4: [
+ ("19", date(1901, 1, 1), DATE_CENTURY),
+ ("1985", date(1985, 1, 1), DATE_YEAR),
+ ("1985-04", date(1985, 4, 1), DATE_EXT_MONTH),
+ ("198504", date(1985, 4, 1), DATE_BAS_MONTH),
+ ("1985-04-12", date(1985, 4, 12), DATE_EXT_COMPLETE),
+ ("19850412", date(1985, 4, 12), DATE_BAS_COMPLETE),
+ ("1985102", date(1985, 4, 12), DATE_BAS_ORD_COMPLETE),
+ ("1985-102", date(1985, 4, 12), DATE_EXT_ORD_COMPLETE),
+ ("1985W155", date(1985, 4, 12), DATE_BAS_WEEK_COMPLETE),
+ ("1985-W15-5", date(1985, 4, 12), DATE_EXT_WEEK_COMPLETE),
+ ("1985W15", date(1985, 4, 8), DATE_BAS_WEEK),
+ ("1985-W15", date(1985, 4, 8), DATE_EXT_WEEK),
+ ("1989-W15", date(1989, 4, 10), DATE_EXT_WEEK),
+ ("1989-W15-5", date(1989, 4, 14), DATE_EXT_WEEK_COMPLETE),
+ ("1-W1-1", None, DATE_BAS_WEEK_COMPLETE),
+ ],
+ 6: [
+ ("+0019", date(1901, 1, 1), DATE_CENTURY),
+ ("+001985", date(1985, 1, 1), DATE_YEAR),
+ ("+001985-04", date(1985, 4, 1), DATE_EXT_MONTH),
+ ("+001985-04-12", date(1985, 4, 12), DATE_EXT_COMPLETE),
+ ("+0019850412", date(1985, 4, 12), DATE_BAS_COMPLETE),
+ ("+001985102", date(1985, 4, 12), DATE_BAS_ORD_COMPLETE),
+ ("+001985-102", date(1985, 4, 12), DATE_EXT_ORD_COMPLETE),
+ ("+001985W155", date(1985, 4, 12), DATE_BAS_WEEK_COMPLETE),
+ ("+001985-W15-5", date(1985, 4, 12), DATE_EXT_WEEK_COMPLETE),
+ ("+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.
- '''
+ """
if expectation is None:
- self.assertRaises(ISO8601Error, parse_date, datestring,
- yeardigits)
+ self.assertRaises(ISO8601Error, parse_date, datestring, yeardigits)
else:
result = parse_date(datestring, yeardigits)
self.assertEqual(result, expectation)
def test_format(self):
- '''
+ """
Take date object and create ISO string from it.
This is the reverse test to test_parse.
- '''
+ """
if expectation is None:
- self.assertRaises(AttributeError,
- date_isoformat, expectation, format,
- yeardigits)
+ self.assertRaises(
+ AttributeError, date_isoformat, expectation, format, yeardigits
+ )
else:
- self.assertEqual(date_isoformat(expectation, format,
- yeardigits),
- datestring)
+ self.assertEqual(
+ date_isoformat(expectation, format, yeardigits), datestring
+ )
return unittest.TestLoader().loadTestsFromTestCase(TestDate)
def test_suite():
- '''
+ """
Construct a TestSuite instance for all test cases.
- '''
+ """
suite = unittest.TestSuite()
for yeardigits, tests in TEST_CASES.items():
for datestring, expectation, format in tests:
- suite.addTest(create_testcase(yeardigits, datestring,
- expectation, format))
+ suite.addTest(create_testcase(yeardigits, datestring, expectation, format))
return suite
@@ -128,5 +132,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='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 85c822f..1e33766 100644
--- a/src/isodate/tests/test_datetime.py
+++ b/src/isodate/tests/test_datetime.py
@@ -24,9 +24,9 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Test cases for the isodatetime module.
-'''
+"""
import unittest
from datetime import datetime
@@ -41,62 +41,113 @@ from isodate import DATE_BAS_WEEK_COMPLETE, DATE_EXT_WEEK_COMPLETE
# the following list contains tuples of ISO datetime strings and the expected
# result from the parse_datetime method. A result of None means an ISO8601Error
# is expected.
-TEST_CASES = [('19850412T1015', datetime(1985, 4, 12, 10, 15),
- DATE_BAS_COMPLETE + 'T' + TIME_BAS_MINUTE,
- '19850412T1015'),
- ('1985-04-12T10:15', datetime(1985, 4, 12, 10, 15),
- DATE_EXT_COMPLETE + 'T' + TIME_EXT_MINUTE,
- '1985-04-12T10:15'),
- ('1985102T1015Z', datetime(1985, 4, 12, 10, 15, tzinfo=UTC),
- DATE_BAS_ORD_COMPLETE + 'T' + TIME_BAS_MINUTE + TZ_BAS,
- '1985102T1015Z'),
- ('1985-102T10:15Z', datetime(1985, 4, 12, 10, 15, tzinfo=UTC),
- DATE_EXT_ORD_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_EXT,
- '1985-102T10:15Z'),
- ('1985W155T1015+0400', datetime(1985, 4, 12, 10, 15,
- tzinfo=FixedOffset(4, 0,
- '+0400')),
- DATE_BAS_WEEK_COMPLETE + 'T' + TIME_BAS_MINUTE + TZ_BAS,
- '1985W155T1015+0400'),
- ('1985-W15-5T10:15+04', datetime(1985, 4, 12, 10, 15,
- tzinfo=FixedOffset(4, 0,
- '+0400'),),
- DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_HOUR,
- '1985-W15-5T10:15+04'),
- ('1985-W15-5T10:15-0430',
- datetime(1985, 4, 12, 10, 15, tzinfo=FixedOffset(-4, -30,
- '-0430'),),
- DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_BAS,
- '1985-W15-5T10:15-0430'),
- ('1985-W15-5T10:15+04:45',
- datetime(1985, 4, 12, 10, 15, tzinfo=FixedOffset(4, 45,
- '+04:45'),),
- DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_EXT,
- '1985-W15-5T10:15+04:45'),
- ('20110410T101225.123000Z',
- datetime(2011, 4, 10, 10, 12, 25, 123000, tzinfo=UTC),
- DATE_BAS_COMPLETE + 'T' + TIME_BAS_COMPLETE + ".%f" + TZ_BAS,
- '20110410T101225.123000Z'),
- ('2012-10-12T08:29:46.069178Z',
- datetime(2012, 10, 12, 8, 29, 46, 69178, tzinfo=UTC),
- DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + '.%f' + TZ_BAS,
- '2012-10-12T08:29:46.069178Z'),
- ('2012-10-12T08:29:46.691780Z',
- datetime(2012, 10, 12, 8, 29, 46, 691780, tzinfo=UTC),
- DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + '.%f' + TZ_BAS,
- '2012-10-12T08:29:46.691780Z'),
- ('2012-10-30T08:55:22.1234567Z',
- datetime(2012, 10, 30, 8, 55, 22, 123457, tzinfo=UTC),
- DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + '.%f' + TZ_BAS,
- '2012-10-30T08:55:22.123457Z'),
- ('2012-10-30T08:55:22.1234561Z',
- 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'),
- ('2014-08-18 14:55:22.123456Z', None,
- DATE_EXT_COMPLETE + 'T' + TIME_EXT_COMPLETE + '.%f' + TZ_BAS,
- '2014-08-18T14:55:22.123456Z'),
- ]
+TEST_CASES = [
+ (
+ "19850412T1015",
+ datetime(1985, 4, 12, 10, 15),
+ DATE_BAS_COMPLETE + "T" + TIME_BAS_MINUTE,
+ "19850412T1015",
+ ),
+ (
+ "1985-04-12T10:15",
+ datetime(1985, 4, 12, 10, 15),
+ DATE_EXT_COMPLETE + "T" + TIME_EXT_MINUTE,
+ "1985-04-12T10:15",
+ ),
+ (
+ "1985102T1015Z",
+ datetime(1985, 4, 12, 10, 15, tzinfo=UTC),
+ DATE_BAS_ORD_COMPLETE + "T" + TIME_BAS_MINUTE + TZ_BAS,
+ "1985102T1015Z",
+ ),
+ (
+ "1985-102T10:15Z",
+ datetime(1985, 4, 12, 10, 15, tzinfo=UTC),
+ DATE_EXT_ORD_COMPLETE + "T" + TIME_EXT_MINUTE + TZ_EXT,
+ "1985-102T10:15Z",
+ ),
+ (
+ "1985W155T1015+0400",
+ datetime(1985, 4, 12, 10, 15, tzinfo=FixedOffset(4, 0, "+0400")),
+ DATE_BAS_WEEK_COMPLETE + "T" + TIME_BAS_MINUTE + TZ_BAS,
+ "1985W155T1015+0400",
+ ),
+ (
+ "1985-W15-5T10:15+04",
+ datetime(
+ 1985,
+ 4,
+ 12,
+ 10,
+ 15,
+ tzinfo=FixedOffset(4, 0, "+0400"),
+ ),
+ DATE_EXT_WEEK_COMPLETE + "T" + TIME_EXT_MINUTE + TZ_HOUR,
+ "1985-W15-5T10:15+04",
+ ),
+ (
+ "1985-W15-5T10:15-0430",
+ datetime(
+ 1985,
+ 4,
+ 12,
+ 10,
+ 15,
+ tzinfo=FixedOffset(-4, -30, "-0430"),
+ ),
+ DATE_EXT_WEEK_COMPLETE + "T" + TIME_EXT_MINUTE + TZ_BAS,
+ "1985-W15-5T10:15-0430",
+ ),
+ (
+ "1985-W15-5T10:15+04:45",
+ datetime(
+ 1985,
+ 4,
+ 12,
+ 10,
+ 15,
+ tzinfo=FixedOffset(4, 45, "+04:45"),
+ ),
+ DATE_EXT_WEEK_COMPLETE + "T" + TIME_EXT_MINUTE + TZ_EXT,
+ "1985-W15-5T10:15+04:45",
+ ),
+ (
+ "20110410T101225.123000Z",
+ datetime(2011, 4, 10, 10, 12, 25, 123000, tzinfo=UTC),
+ DATE_BAS_COMPLETE + "T" + TIME_BAS_COMPLETE + ".%f" + TZ_BAS,
+ "20110410T101225.123000Z",
+ ),
+ (
+ "2012-10-12T08:29:46.069178Z",
+ datetime(2012, 10, 12, 8, 29, 46, 69178, tzinfo=UTC),
+ DATE_EXT_COMPLETE + "T" + TIME_EXT_COMPLETE + ".%f" + TZ_BAS,
+ "2012-10-12T08:29:46.069178Z",
+ ),
+ (
+ "2012-10-12T08:29:46.691780Z",
+ datetime(2012, 10, 12, 8, 29, 46, 691780, tzinfo=UTC),
+ DATE_EXT_COMPLETE + "T" + TIME_EXT_COMPLETE + ".%f" + TZ_BAS,
+ "2012-10-12T08:29:46.691780Z",
+ ),
+ (
+ "2012-10-30T08:55:22.1234567Z",
+ datetime(2012, 10, 30, 8, 55, 22, 123457, tzinfo=UTC),
+ DATE_EXT_COMPLETE + "T" + TIME_EXT_COMPLETE + ".%f" + TZ_BAS,
+ "2012-10-30T08:55:22.123457Z",
+ ),
+ (
+ "2012-10-30T08:55:22.1234561Z",
+ 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",
+ ),
+ (
+ "2014-08-18 14:55:22.123456Z",
+ None,
+ DATE_EXT_COMPLETE + "T" + TIME_EXT_COMPLETE + ".%f" + TZ_BAS,
+ "2014-08-18T14:55:22.123456Z",
+ ),
+]
def create_testcase(datetimestring, expectation, format, output):
@@ -108,43 +159,42 @@ def create_testcase(datetimestring, expectation, format, output):
"""
class TestDateTime(unittest.TestCase):
- '''
+ """
A test case template to parse an ISO datetime string into a
datetime object.
- '''
+ """
def test_parse(self):
- '''
+ """
Parse an ISO datetime string and compare it to the expected value.
- '''
+ """
if expectation is None:
self.assertRaises(ISO8601Error, parse_datetime, datetimestring)
else:
self.assertEqual(parse_datetime(datetimestring), expectation)
def test_format(self):
- '''
+ """
Take datetime object and create ISO string from it.
This is the reverse test to test_parse.
- '''
+ """
if expectation is None:
- self.assertRaises(AttributeError,
- datetime_isoformat, expectation, format)
+ self.assertRaises(
+ AttributeError, datetime_isoformat, expectation, format
+ )
else:
- self.assertEqual(datetime_isoformat(expectation, format),
- output)
+ self.assertEqual(datetime_isoformat(expectation, format), output)
return unittest.TestLoader().loadTestsFromTestCase(TestDateTime)
def test_suite():
- '''
+ """
Construct a TestSuite instance for all test cases.
- '''
+ """
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
@@ -153,5 +203,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='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 b0e0332..9f19378 100644
--- a/src/isodate/tests/test_duration.py
+++ b/src/isodate/tests/test_duration.py
@@ -24,9 +24,9 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Test cases for the isoduration module.
-'''
+"""
import unittest
import operator
from datetime import timedelta, date, datetime
@@ -37,47 +37,40 @@ from isodate import D_DEFAULT, D_WEEK, D_ALT_EXT, duration_isoformat
# the following list contains tuples of ISO duration strings and the expected
# result from the parse_duration method. A result of None means an ISO8601Error
# is expected.
-PARSE_TEST_CASES = {'P18Y9M4DT11H9M8S': (Duration(4, 8, 0, 0, 9, 11, 0, 9, 18),
- D_DEFAULT, None),
- 'P2W': (timedelta(weeks=2), D_WEEK, None),
- 'P3Y6M4DT12H30M5S': (Duration(4, 5, 0, 0, 30, 12, 0, 6, 3),
- D_DEFAULT, None),
- 'P23DT23H': (timedelta(hours=23, days=23),
- D_DEFAULT, None),
- 'P4Y': (Duration(years=4), D_DEFAULT, None),
- 'P1M': (Duration(months=1), D_DEFAULT, None),
- 'PT1M': (timedelta(minutes=1), D_DEFAULT, None),
- 'P0.5Y': (Duration(years=0.5), D_DEFAULT, None),
- 'PT36H': (timedelta(hours=36), D_DEFAULT, 'P1DT12H'),
- 'P1DT12H': (timedelta(days=1, hours=12), D_DEFAULT, None),
- '+P11D': (timedelta(days=11), D_DEFAULT, 'P11D'),
- '-P2W': (timedelta(weeks=-2), D_WEEK, None),
- '-P2.2W': (timedelta(weeks=-2.2), D_DEFAULT,
- '-P15DT9H36M'),
- 'P1DT2H3M4S': (timedelta(days=1, hours=2, minutes=3,
- 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),
- 'PT2H': (timedelta(hours=2), D_DEFAULT, None),
- 'PT2.3H': (timedelta(hours=2.3), D_DEFAULT, 'PT2H18M'),
- 'PT2H3M4S': (timedelta(hours=2, minutes=3, seconds=4),
- D_DEFAULT, None),
- 'PT3M4S': (timedelta(minutes=3, seconds=4), D_DEFAULT,
- None),
- 'PT22S': (timedelta(seconds=22), D_DEFAULT, None),
- 'PT22.22S': (timedelta(seconds=22.22), 'PT%S.%fS',
- 'PT22.220000S'),
- '-P2Y': (Duration(years=-2), D_DEFAULT, None),
- '-P3Y6M4DT12H30M5S': (Duration(-4, -5, 0, 0, -30, -12, 0,
- -6, -3), D_DEFAULT, None),
- '-P1DT2H3M4S': (timedelta(days=-1, hours=-2, minutes=-3,
- seconds=-4), D_DEFAULT, None),
- # alternative format
- 'P0018-09-04T11:09:08': (Duration(4, 8, 0, 0, 9, 11, 0, 9,
- 18), D_ALT_EXT, None),
- # 'PT000022.22': timedelta(seconds=22.22),
- }
+PARSE_TEST_CASES = {
+ "P18Y9M4DT11H9M8S": (Duration(4, 8, 0, 0, 9, 11, 0, 9, 18), D_DEFAULT, None),
+ "P2W": (timedelta(weeks=2), D_WEEK, None),
+ "P3Y6M4DT12H30M5S": (Duration(4, 5, 0, 0, 30, 12, 0, 6, 3), D_DEFAULT, None),
+ "P23DT23H": (timedelta(hours=23, days=23), D_DEFAULT, None),
+ "P4Y": (Duration(years=4), D_DEFAULT, None),
+ "P1M": (Duration(months=1), D_DEFAULT, None),
+ "PT1M": (timedelta(minutes=1), D_DEFAULT, None),
+ "P0.5Y": (Duration(years=0.5), D_DEFAULT, None),
+ "PT36H": (timedelta(hours=36), D_DEFAULT, "P1DT12H"),
+ "P1DT12H": (timedelta(days=1, hours=12), D_DEFAULT, None),
+ "+P11D": (timedelta(days=11), D_DEFAULT, "P11D"),
+ "-P2W": (timedelta(weeks=-2), D_WEEK, None),
+ "-P2.2W": (timedelta(weeks=-2.2), D_DEFAULT, "-P15DT9H36M"),
+ "P1DT2H3M4S": (timedelta(days=1, hours=2, minutes=3, 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),
+ "PT2H": (timedelta(hours=2), D_DEFAULT, None),
+ "PT2.3H": (timedelta(hours=2.3), D_DEFAULT, "PT2H18M"),
+ "PT2H3M4S": (timedelta(hours=2, minutes=3, seconds=4), D_DEFAULT, None),
+ "PT3M4S": (timedelta(minutes=3, seconds=4), D_DEFAULT, None),
+ "PT22S": (timedelta(seconds=22), D_DEFAULT, None),
+ "PT22.22S": (timedelta(seconds=22.22), "PT%S.%fS", "PT22.220000S"),
+ "-P2Y": (Duration(years=-2), D_DEFAULT, None),
+ "-P3Y6M4DT12H30M5S": (Duration(-4, -5, 0, 0, -30, -12, 0, -6, -3), D_DEFAULT, None),
+ "-P1DT2H3M4S": (
+ timedelta(days=-1, hours=-2, minutes=-3, seconds=-4),
+ D_DEFAULT,
+ None,
+ ),
+ # alternative format
+ "P0018-09-04T11:09:08": (Duration(4, 8, 0, 0, 9, 11, 0, 9, 18), D_ALT_EXT, None),
+ # 'PT000022.22': timedelta(seconds=22.22),
+}
# d1 d2 '+', '-', '>'
# A list of test cases to test addition and subtraction between datetime and
@@ -85,188 +78,174 @@ PARSE_TEST_CASES = {'P18Y9M4DT11H9M8S': (Duration(4, 8, 0, 0, 9, 11, 0, 9, 18),
# each tuple contains 2 duration strings, and a result string for addition and
# one for subtraction. The last value says, if the first duration is greater
# than the second.
-MATH_TEST_CASES = (('P5Y7M1DT9H45M16.72S', 'PT27M24.68S',
- 'P5Y7M1DT10H12M41.4S', 'P5Y7M1DT9H17M52.04S', None),
- ('PT28M12.73S', 'PT56M29.92S',
- 'PT1H24M42.65S', '-PT28M17.19S', False),
- ('P3Y7M23DT5H25M0.33S', 'PT1H1.95S',
- 'P3Y7M23DT6H25M2.28S', 'P3Y7M23DT4H24M58.38S', None),
- ('PT1H1.95S', 'P3Y7M23DT5H25M0.33S',
- 'P3Y7M23DT6H25M2.28S', '-P3Y7M23DT4H24M58.38S', None),
- ('P1332DT55M0.33S', 'PT1H1.95S',
- 'P1332DT1H55M2.28S', 'P1331DT23H54M58.38S', True),
- ('PT1H1.95S', 'P1332DT55M0.33S',
- 'P1332DT1H55M2.28S', '-P1331DT23H54M58.38S', False))
+MATH_TEST_CASES = (
+ (
+ "P5Y7M1DT9H45M16.72S",
+ "PT27M24.68S",
+ "P5Y7M1DT10H12M41.4S",
+ "P5Y7M1DT9H17M52.04S",
+ None,
+ ),
+ ("PT28M12.73S", "PT56M29.92S", "PT1H24M42.65S", "-PT28M17.19S", False),
+ (
+ "P3Y7M23DT5H25M0.33S",
+ "PT1H1.95S",
+ "P3Y7M23DT6H25M2.28S",
+ "P3Y7M23DT4H24M58.38S",
+ None,
+ ),
+ (
+ "PT1H1.95S",
+ "P3Y7M23DT5H25M0.33S",
+ "P3Y7M23DT6H25M2.28S",
+ "-P3Y7M23DT4H24M58.38S",
+ None,
+ ),
+ ("P1332DT55M0.33S", "PT1H1.95S", "P1332DT1H55M2.28S", "P1331DT23H54M58.38S", True),
+ (
+ "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, 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)),
- )
+)
# A list of test cases of multiplications of durations
# are compared against a given expected result.
DATE_MUL_TEST_CASES = (
- (Duration(years=1, months=1),
- 3,
- Duration(years=3, months=3)),
- (Duration(years=1, months=1),
- -3,
- Duration(years=-3, months=-3)),
- (3,
- Duration(years=1, months=1),
- Duration(years=3, months=3)),
- (-3,
- Duration(years=1, months=1),
- Duration(years=-3, months=-3)),
- (5,
- Duration(years=2, minutes=40),
- Duration(years=10, hours=3, minutes=20)),
- (-5,
- Duration(years=2, minutes=40),
- Duration(years=-10, hours=-3, minutes=-20)),
- (7,
- Duration(years=1, months=2, weeks=40),
- Duration(years=8, months=2, weeks=280)))
+ (Duration(years=1, months=1), 3, Duration(years=3, months=3)),
+ (Duration(years=1, months=1), -3, Duration(years=-3, months=-3)),
+ (3, Duration(years=1, months=1), Duration(years=3, months=3)),
+ (-3, Duration(years=1, months=1), Duration(years=-3, months=-3)),
+ (5, Duration(years=2, minutes=40), Duration(years=10, hours=3, minutes=20)),
+ (-5, Duration(years=2, minutes=40), Duration(years=-10, hours=-3, minutes=-20)),
+ (7, Duration(years=1, months=2, weeks=40), Duration(years=8, months=2, weeks=280)),
+)
class DurationTest(unittest.TestCase):
- '''
+ """
This class tests various other aspects of the isoduration module,
which are not covered with the test cases listed above.
- '''
+ """
def test_associative(self):
- '''
+ """
Adding 2 durations to a date is not associative.
- '''
+ """
days1 = Duration(days=1)
months1 = Duration(months=1)
start = date(2000, 3, 30)
@@ -275,53 +254,67 @@ class DurationTest(unittest.TestCase):
self.assertNotEqual(res1, res2)
def test_typeerror(self):
- '''
+ """
Test if TypError is raised with certain parameters.
- '''
+ """
self.assertRaises(TypeError, parse_duration, date(2000, 1, 1))
- self.assertRaises(TypeError, operator.sub, Duration(years=1),
- date(2000, 1, 1))
- self.assertRaises(TypeError, operator.sub, 'raise exc',
- Duration(years=1))
- self.assertRaises(TypeError, operator.add,
- Duration(years=1, months=1, weeks=5),
- 'raise exception')
- self.assertRaises(TypeError, operator.add, 'raise exception',
- Duration(years=1, months=1, weeks=5))
- self.assertRaises(TypeError, operator.mul,
- Duration(years=1, months=1, weeks=5),
- 'raise exception')
- self.assertRaises(TypeError, operator.mul, 'raise exception',
- Duration(years=1, months=1, weeks=5))
- self.assertRaises(TypeError, operator.mul,
- Duration(years=1, months=1, weeks=5),
- 3.14)
- self.assertRaises(TypeError, operator.mul, 3.14,
- Duration(years=1, months=1, weeks=5))
+ self.assertRaises(TypeError, operator.sub, Duration(years=1), date(2000, 1, 1))
+ self.assertRaises(TypeError, operator.sub, "raise exc", Duration(years=1))
+ self.assertRaises(
+ TypeError,
+ operator.add,
+ Duration(years=1, months=1, weeks=5),
+ "raise exception",
+ )
+ self.assertRaises(
+ TypeError,
+ operator.add,
+ "raise exception",
+ Duration(years=1, months=1, weeks=5),
+ )
+ self.assertRaises(
+ TypeError,
+ operator.mul,
+ Duration(years=1, months=1, weeks=5),
+ "raise exception",
+ )
+ self.assertRaises(
+ TypeError,
+ operator.mul,
+ "raise exception",
+ Duration(years=1, months=1, weeks=5),
+ )
+ self.assertRaises(
+ TypeError, operator.mul, Duration(years=1, months=1, weeks=5), 3.14
+ )
+ self.assertRaises(
+ TypeError, operator.mul, 3.14, Duration(years=1, months=1, weeks=5)
+ )
def test_parseerror(self):
- '''
+ """
Test for unparseable duration string.
- '''
- self.assertRaises(ISO8601Error, parse_duration, 'T10:10:10')
+ """
+ self.assertRaises(ISO8601Error, parse_duration, "T10:10:10")
def test_repr(self):
- '''
+ """
Test __repr__ and __str__ for Duration objects.
- '''
+ """
dur = Duration(10, 10, years=10, months=10)
- self.assertEqual('10 years, 10 months, 10 days, 0:00:10', str(dur))
- self.assertEqual('isodate.duration.Duration(10, 10, 0,'
- ' years=10, months=10)', repr(dur))
+ self.assertEqual("10 years, 10 months, 10 days, 0:00:10", str(dur))
+ self.assertEqual(
+ "isodate.duration.Duration(10, 10, 0," " years=10, months=10)", repr(dur)
+ )
dur = Duration(months=0)
- self.assertEqual('0:00:00', str(dur))
+ self.assertEqual("0:00:00", str(dur))
dur = Duration(months=1)
- self.assertEqual('1 month, 0:00:00', str(dur))
+ self.assertEqual("1 month, 0:00:00", str(dur))
def test_hash(self):
- '''
+ """
Test __hash__ for Duration objects.
- '''
+ """
dur1 = Duration(10, 10, years=10, months=10)
dur2 = Duration(9, 9, years=9, months=9)
dur3 = Duration(10, 10, years=10, months=10)
@@ -336,12 +329,11 @@ class DurationTest(unittest.TestCase):
self.assertEqual(len(durSet), 2)
def test_neg(self):
- '''
+ """
Test __neg__ for Duration objects.
- '''
+ """
self.assertEqual(-Duration(0), Duration(0))
- self.assertEqual(-Duration(years=1, months=1),
- Duration(years=-1, months=-1))
+ self.assertEqual(-Duration(years=1, months=1), Duration(years=-1, months=-1))
self.assertEqual(-Duration(years=1, months=1), Duration(months=-13))
self.assertNotEqual(-Duration(years=1), timedelta(days=-365))
self.assertNotEqual(-timedelta(days=365), Duration(years=-1))
@@ -350,41 +342,34 @@ class DurationTest(unittest.TestCase):
# self.assertNotEqual(-timedelta(days=10), -Duration(days=10))
def test_format(self):
- '''
+ """
Test various other strftime combinations.
- '''
- self.assertEqual(duration_isoformat(Duration(0)), 'P0D')
- self.assertEqual(duration_isoformat(-Duration(0)), 'P0D')
- self.assertEqual(duration_isoformat(Duration(seconds=10)), 'PT10S')
- self.assertEqual(duration_isoformat(Duration(years=-1, months=-1)),
- '-P1Y1M')
- self.assertEqual(duration_isoformat(-Duration(years=1, months=1)),
- '-P1Y1M')
- self.assertEqual(duration_isoformat(-Duration(years=-1, months=-1)),
- 'P1Y1M')
- self.assertEqual(duration_isoformat(-Duration(years=-1, months=-1)),
- 'P1Y1M')
- dur = Duration(years=3, months=7, days=23, hours=5, minutes=25,
- milliseconds=330)
- self.assertEqual(duration_isoformat(dur), 'P3Y7M23DT5H25M0.33S')
- self.assertEqual(duration_isoformat(-dur), '-P3Y7M23DT5H25M0.33S')
+ """
+ self.assertEqual(duration_isoformat(Duration(0)), "P0D")
+ self.assertEqual(duration_isoformat(-Duration(0)), "P0D")
+ self.assertEqual(duration_isoformat(Duration(seconds=10)), "PT10S")
+ self.assertEqual(duration_isoformat(Duration(years=-1, months=-1)), "-P1Y1M")
+ self.assertEqual(duration_isoformat(-Duration(years=1, months=1)), "-P1Y1M")
+ self.assertEqual(duration_isoformat(-Duration(years=-1, months=-1)), "P1Y1M")
+ self.assertEqual(duration_isoformat(-Duration(years=-1, months=-1)), "P1Y1M")
+ dur = Duration(
+ years=3, months=7, days=23, hours=5, minutes=25, milliseconds=330
+ )
+ self.assertEqual(duration_isoformat(dur), "P3Y7M23DT5H25M0.33S")
+ self.assertEqual(duration_isoformat(-dur), "-P3Y7M23DT5H25M0.33S")
def test_equal(self):
- '''
+ """
Test __eq__ and __ne__ methods.
- '''
- self.assertEqual(Duration(years=1, months=1),
- Duration(years=1, months=1))
+ """
+ self.assertEqual(Duration(years=1, months=1), Duration(years=1, months=1))
self.assertEqual(Duration(years=1, months=1), Duration(months=13))
- self.assertNotEqual(Duration(years=1, months=2),
- Duration(years=1, months=1))
+ self.assertNotEqual(Duration(years=1, months=2), Duration(years=1, months=1))
self.assertNotEqual(Duration(years=1, months=1), Duration(months=14))
self.assertNotEqual(Duration(years=1), timedelta(days=365))
- self.assertFalse(Duration(years=1, months=1) !=
- Duration(years=1, months=1))
+ self.assertFalse(Duration(years=1, months=1) != Duration(years=1, months=1))
self.assertFalse(Duration(years=1, months=1) != Duration(months=13))
- self.assertTrue(Duration(years=1, months=2) !=
- Duration(years=1, months=1))
+ self.assertTrue(Duration(years=1, months=2) != Duration(years=1, months=1))
self.assertTrue(Duration(years=1, months=1) != Duration(months=14))
self.assertTrue(Duration(years=1) != timedelta(days=365))
self.assertEqual(Duration(days=1), timedelta(days=1))
@@ -393,15 +378,13 @@ class DurationTest(unittest.TestCase):
# self.assertNotEqual(timedelta(days=1), Duration(days=1))
def test_totimedelta(self):
- '''
+ """
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)
@@ -419,31 +402,31 @@ def create_parsetestcase(durationstring, expectation, format, altstr):
"""
class TestParseDuration(unittest.TestCase):
- '''
+ """
A test case template to parse an ISO duration string into a
timedelta or Duration object.
- '''
+ """
def test_parse(self):
- '''
+ """
Parse an ISO duration string and compare it to the expected value.
- '''
+ """
result = parse_duration(durationstring)
self.assertEqual(result, expectation)
def test_format(self):
- '''
+ """
Take duration/timedelta object and create ISO string from it.
This is the reverse test to test_parse.
- '''
+ """
if altstr:
- self.assertEqual(duration_isoformat(expectation, format),
- altstr)
+ self.assertEqual(duration_isoformat(expectation, format), altstr)
else:
# if durationstring == '-P2W':
# import pdb; pdb.set_trace()
- self.assertEqual(duration_isoformat(expectation, format),
- durationstring)
+ self.assertEqual(
+ duration_isoformat(expectation, format), durationstring
+ )
return unittest.TestLoader().loadTestsFromTestCase(TestParseDuration)
@@ -462,34 +445,36 @@ def create_mathtestcase(dur1, dur2, resadd, ressub, resge):
ressub = parse_duration(ressub)
class TestMathDuration(unittest.TestCase):
- '''
+ """
A test case template test addition, subtraction and >
operators for Duration objects.
- '''
+ """
def test_add(self):
- '''
+ """
Test operator + (__add__, __radd__)
- '''
+ """
self.assertEqual(dur1 + dur2, resadd)
def test_sub(self):
- '''
+ """
Test operator - (__sub__, __rsub__)
- '''
+ """
self.assertEqual(dur1 - dur2, ressub)
def test_ge(self):
- '''
+ """
Test operator > and <
- '''
+ """
+
def dogetest():
- ''' Test greater than.'''
+ """Test greater than."""
return dur1 > dur2
def doletest():
- ''' Test less than.'''
+ """Test less than."""
return dur1 < dur2
+
if resge is None:
self.assertRaises(TypeError, dogetest)
self.assertRaises(TypeError, doletest)
@@ -509,21 +494,21 @@ def create_datetestcase(start, tdelta, duration):
"""
class TestDateCalc(unittest.TestCase):
- '''
+ """
A test case template test addition, subtraction
operators for Duration objects.
- '''
+ """
def test_add(self):
- '''
+ """
Test operator +.
- '''
+ """
self.assertEqual(start + tdelta, start + duration)
def test_sub(self):
- '''
+ """
Test operator -.
- '''
+ """
self.assertEqual(start - tdelta, start - duration)
return unittest.TestLoader().loadTestsFromTestCase(TestDateCalc)
@@ -538,14 +523,14 @@ def create_datecalctestcase(start, duration, expectation):
"""
class TestDateCalc(unittest.TestCase):
- '''
+ """
A test case template test addition operators for Duration objects.
- '''
+ """
def test_calc(self):
- '''
+ """
Test operator +.
- '''
+ """
if expectation is None:
self.assertRaises(ValueError, operator.add, start, duration)
else:
@@ -563,28 +548,26 @@ def create_datemultestcase(operand1, operand2, expectation):
"""
class TestDateMul(unittest.TestCase):
- '''
+ """
A test case template test addition operators for Duration objects.
- '''
+ """
def test_mul(self):
- '''
+ """
Test operator *.
- '''
+ """
self.assertEqual(operand1 * operand2, expectation)
return unittest.TestLoader().loadTestsFromTestCase(TestDateMul)
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():
- suite.addTest(create_parsetestcase(durationstring, expectation,
- format, altstr))
+ for durationstring, (expectation, format, altstr) in PARSE_TEST_CASES.items():
+ suite.addTest(create_parsetestcase(durationstring, expectation, format, altstr))
for testdata in MATH_TEST_CASES:
suite.addTest(create_mathtestcase(*testdata))
for testdata in DATE_TEST_CASES:
@@ -602,5 +585,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
+if __name__ == "__main__":
+ unittest.main(defaultTest="test_suite")
diff --git a/src/isodate/tests/test_pickle.py b/src/isodate/tests/test_pickle.py
index 7fc6213..01b56e6 100644
--- a/src/isodate/tests/test_pickle.py
+++ b/src/isodate/tests/test_pickle.py
@@ -1,31 +1,31 @@
import unittest
-from six.moves import cPickle as pickle
+import pickle
import isodate
class TestPickle(unittest.TestCase):
- '''
+ """
A test case template to parse an ISO datetime string into a
datetime object.
- '''
+ """
def test_pickle_datetime(self):
- '''
+ """
Parse an ISO datetime string and compare it to the expected value.
- '''
- dti = isodate.parse_datetime('2012-10-26T09:33+00:00')
+ """
+ dti = isodate.parse_datetime("2012-10-26T09:33+00:00")
for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
pikl = pickle.dumps(dti, proto)
- self.assertEqual(dti, pickle.loads(pikl),
- "pickle proto %d failed" % proto)
+ self.assertEqual(dti, pickle.loads(pikl), "pickle proto %d failed" % proto)
def test_pickle_duration(self):
- '''
+ """
Pickle / unpickle duration objects.
- '''
+ """
from isodate.duration import Duration
+
dur = Duration()
failed = []
for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
@@ -35,20 +35,19 @@ class TestPickle(unittest.TestCase):
raise Exception("not equal")
except Exception as e:
failed.append("pickle proto %d failed (%s)" % (proto, repr(e)))
- self.assertEqual(len(failed), 0, "pickle protos failed: %s" %
- str(failed))
+ self.assertEqual(len(failed), 0, "pickle protos failed: %s" % str(failed))
def test_pickle_utc(self):
- '''
+ """
isodate.UTC objects remain the same after pickling.
- '''
+ """
self.assertTrue(isodate.UTC is pickle.loads(pickle.dumps(isodate.UTC)))
def test_suite():
- '''
+ """
Construct a TestSuite instance for all test cases.
- '''
+ """
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestPickle))
return suite
@@ -59,5 +58,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
+if __name__ == "__main__":
+ unittest.main(defaultTest="test_suite")
diff --git a/src/isodate/tests/test_strf.py b/src/isodate/tests/test_strf.py
index 1aa76c7..73cda0f 100644
--- a/src/isodate/tests/test_strf.py
+++ b/src/isodate/tests/test_strf.py
@@ -24,9 +24,9 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Test cases for the isodate module.
-'''
+"""
import unittest
import time
from datetime import datetime, timedelta
@@ -36,19 +36,30 @@ from isodate import DT_EXT_COMPLETE
from isodate import tzinfo
-TEST_CASES = ((datetime(2012, 12, 25, 13, 30, 0, 0, LOCAL), DT_EXT_COMPLETE,
- "2012-12-25T13:30:00+10:00"),
- # DST ON
- (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",
- "2012-10-12T08:29:46.069178"),
- (datetime(2012, 10, 12, 8, 29, 46, 691780),
- "%Y-%m-%dT%H:%M:%S.%f",
- "2012-10-12T08:29:46.691780"),
- )
+TEST_CASES = (
+ (
+ datetime(2012, 12, 25, 13, 30, 0, 0, LOCAL),
+ DT_EXT_COMPLETE,
+ "2012-12-25T13:30:00+10:00",
+ ),
+ # DST ON
+ (
+ 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",
+ "2012-10-12T08:29:46.069178",
+ ),
+ (
+ datetime(2012, 10, 12, 8, 29, 46, 691780),
+ "%Y-%m-%dT%H:%M:%S.%f",
+ "2012-10-12T08:29:46.691780",
+ ),
+)
def create_testcase(dt, format, expectation):
@@ -60,9 +71,9 @@ def create_testcase(dt, format, expectation):
"""
class TestDate(unittest.TestCase):
- '''
+ """
A test case template to test ISO date formatting.
- '''
+ """
# local time zone mock function
def localtime_mock(self, secs):
@@ -70,23 +81,31 @@ def create_testcase(dt, format, expectation):
mock time.localtime so that it always returns a time_struct with
tm_idst=1
"""
- tt = self.ORIG['localtime'](secs)
+ tt = self.ORIG["localtime"](secs)
# befor 2000 everything is dst, after 2000 no dst.
if tt.tm_year < 2000:
dst = 1
else:
dst = 0
- tt = (tt.tm_year, tt.tm_mon, tt.tm_mday,
- tt.tm_hour, tt.tm_min, tt.tm_sec,
- tt.tm_wday, tt.tm_yday, dst)
+ tt = (
+ tt.tm_year,
+ tt.tm_mon,
+ tt.tm_mday,
+ tt.tm_hour,
+ tt.tm_min,
+ tt.tm_sec,
+ tt.tm_wday,
+ tt.tm_yday,
+ dst,
+ )
return time.struct_time(tt)
def setUp(self):
self.ORIG = {}
- self.ORIG['STDOFFSET'] = tzinfo.STDOFFSET
- self.ORIG['DSTOFFSET'] = tzinfo.DSTOFFSET
- self.ORIG['DSTDIFF'] = tzinfo.DSTDIFF
- self.ORIG['localtime'] = time.localtime
+ self.ORIG["STDOFFSET"] = tzinfo.STDOFFSET
+ self.ORIG["DSTOFFSET"] = tzinfo.DSTOFFSET
+ 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
@@ -97,30 +116,28 @@ def create_testcase(dt, format, expectation):
def tearDown(self):
# restore test fixtures
- tzinfo.STDOFFSET = self.ORIG['STDOFFSET']
- tzinfo.DSTOFFSET = self.ORIG['DSTOFFSET']
- tzinfo.DSTDIFF = self.ORIG['DSTDIFF']
- time.localtime = self.ORIG['localtime']
+ tzinfo.STDOFFSET = self.ORIG["STDOFFSET"]
+ tzinfo.DSTOFFSET = self.ORIG["DSTOFFSET"]
+ tzinfo.DSTDIFF = self.ORIG["DSTDIFF"]
+ time.localtime = self.ORIG["localtime"]
def test_format(self):
- '''
+ """
Take date object and create ISO string from it.
This is the reverse test to test_parse.
- '''
+ """
if expectation is None:
- self.assertRaises(AttributeError,
- strftime(dt, format))
+ self.assertRaises(AttributeError, strftime(dt, format))
else:
- self.assertEqual(strftime(dt, format),
- expectation)
+ self.assertEqual(strftime(dt, format), expectation)
return unittest.TestLoader().loadTestsFromTestCase(TestDate)
def test_suite():
- '''
+ """
Construct a TestSuite instance for all test cases.
- '''
+ """
suite = unittest.TestSuite()
for dt, format, expectation in TEST_CASES:
suite.addTest(create_testcase(dt, format, expectation))
@@ -132,5 +149,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='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 fe96dab..680f4ab 100644
--- a/src/isodate/tests/test_time.py
+++ b/src/isodate/tests/test_time.py
@@ -24,9 +24,9 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT
##############################################################################
-'''
+"""
Test cases for the isotime module.
-'''
+"""
import unittest
from datetime import time
@@ -39,57 +39,78 @@ from isodate import TZ_BAS, TZ_EXT, TZ_HOUR
# the following list contains tuples of ISO time strings and the expected
# result from the parse_time method. A result of None means an ISO8601Error
# is expected.
-TEST_CASES = [('232050', time(23, 20, 50), TIME_BAS_COMPLETE + TZ_BAS),
- ('23:20:50', time(23, 20, 50), TIME_EXT_COMPLETE + TZ_EXT),
- ('2320', time(23, 20), TIME_BAS_MINUTE),
- ('23:20', time(23, 20), TIME_EXT_MINUTE),
- ('23', time(23), TIME_HOUR),
- ('232050,5', time(23, 20, 50, 500000), None),
- ('23:20:50.5', time(23, 20, 50, 500000), None),
- # test precision
- ('15:33:42.123456', time(15, 33, 42, 123456), None),
- ('15:33:42.1234564', time(15, 33, 42, 123456), None),
- ('15:33:42.1234557', time(15, 33, 42, 123456), None),
- ('2320,8', time(23, 20, 48), None),
- ('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),
- ('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),
- ('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),
- ('152746-0500', time(15, 27, 46,
- tzinfo=FixedOffset(-5, 0, '-0500')),
- TIME_BAS_COMPLETE + TZ_BAS),
- ('152746+01', time(15, 27, 46,
- tzinfo=FixedOffset(1, 0, '+01:00')),
- TIME_BAS_COMPLETE + TZ_HOUR),
- ('152746-05', time(15, 27, 46,
- tzinfo=FixedOffset(-5, -0, '-05:00')),
- 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),
- ('15:27:46-05:00', time(15, 27, 46,
- tzinfo=FixedOffset(-5, -0, '-05:00')),
- TIME_EXT_COMPLETE + TZ_EXT),
- ('15:27:46+01', time(15, 27, 46,
- tzinfo=FixedOffset(1, 0, '+01:00')),
- TIME_EXT_COMPLETE + TZ_HOUR),
- ('15:27:46-05', time(15, 27, 46,
- tzinfo=FixedOffset(-5, -0, '-05:00')),
- TIME_EXT_COMPLETE + TZ_HOUR),
- ('15:27:46-05:30', time(15, 27, 46,
- tzinfo=FixedOffset(-5, -30, '-05:30')),
- TIME_EXT_COMPLETE + TZ_EXT),
- ('15:27:46-0545', time(15, 27, 46,
- tzinfo=FixedOffset(-5, -45, '-0545')),
- TIME_EXT_COMPLETE + TZ_BAS),
- ('1:17:30', None, TIME_EXT_COMPLETE)]
+TEST_CASES = [
+ ("232050", time(23, 20, 50), TIME_BAS_COMPLETE + TZ_BAS),
+ ("23:20:50", time(23, 20, 50), TIME_EXT_COMPLETE + TZ_EXT),
+ ("2320", time(23, 20), TIME_BAS_MINUTE),
+ ("23:20", time(23, 20), TIME_EXT_MINUTE),
+ ("23", time(23), TIME_HOUR),
+ ("232050,5", time(23, 20, 50, 500000), None),
+ ("23:20:50.5", time(23, 20, 50, 500000), None),
+ # test precision
+ ("15:33:42.123456", time(15, 33, 42, 123456), None),
+ ("15:33:42.1234564", time(15, 33, 42, 123456), None),
+ ("15:33:42.1234557", time(15, 33, 42, 123456), None),
+ ("2320,8", time(23, 20, 48), None),
+ ("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),
+ ("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),
+ ("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,
+ ),
+ (
+ "152746-0500",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, 0, "-0500")),
+ TIME_BAS_COMPLETE + TZ_BAS,
+ ),
+ (
+ "152746+01",
+ time(15, 27, 46, tzinfo=FixedOffset(1, 0, "+01:00")),
+ TIME_BAS_COMPLETE + TZ_HOUR,
+ ),
+ (
+ "152746-05",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, -0, "-05:00")),
+ 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,
+ ),
+ (
+ "15:27:46-05:00",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, -0, "-05:00")),
+ TIME_EXT_COMPLETE + TZ_EXT,
+ ),
+ (
+ "15:27:46+01",
+ time(15, 27, 46, tzinfo=FixedOffset(1, 0, "+01:00")),
+ TIME_EXT_COMPLETE + TZ_HOUR,
+ ),
+ (
+ "15:27:46-05",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, -0, "-05:00")),
+ TIME_EXT_COMPLETE + TZ_HOUR,
+ ),
+ (
+ "15:27:46-05:30",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, -30, "-05:30")),
+ TIME_EXT_COMPLETE + TZ_EXT,
+ ),
+ (
+ "15:27:46-0545",
+ time(15, 27, 46, tzinfo=FixedOffset(-5, -45, "-0545")),
+ TIME_EXT_COMPLETE + TZ_BAS,
+ ),
+ ("1:17:30", None, TIME_EXT_COMPLETE),
+]
def create_testcase(timestring, expectation, format):
@@ -101,15 +122,15 @@ def create_testcase(timestring, expectation, format):
"""
class TestTime(unittest.TestCase):
- '''
+ """
A test case template to parse an ISO time string into a time
object.
- '''
+ """
def test_parse(self):
- '''
+ """
Parse an ISO time string and compare it to the expected value.
- '''
+ """
if expectation is None:
self.assertRaises(ISO8601Error, parse_time, timestring)
else:
@@ -117,24 +138,22 @@ def create_testcase(timestring, expectation, format):
self.assertEqual(result, expectation)
def test_format(self):
- '''
+ """
Take time object and create ISO string from it.
This is the reverse test to test_parse.
- '''
+ """
if expectation is None:
- self.assertRaises(AttributeError,
- time_isoformat, expectation, format)
+ self.assertRaises(AttributeError, time_isoformat, expectation, format)
elif format is not None:
- self.assertEqual(time_isoformat(expectation, format),
- timestring)
+ self.assertEqual(time_isoformat(expectation, format), timestring)
return unittest.TestLoader().loadTestsFromTestCase(TestTime)
def test_suite():
- '''
+ """
Construct a TestSuite instance for all test cases.
- '''
+ """
suite = unittest.TestSuite()
for timestring, expectation, format in TEST_CASES:
suite.addTest(create_testcase(timestring, expectation, format))
@@ -146,5 +165,5 @@ def load_tests(loader, tests, pattern):
return test_suite()
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
+if __name__ == "__main__":
+ unittest.main(defaultTest="test_suite")
diff --git a/src/isodate/tzinfo.py b/src/isodate/tzinfo.py
index 5d3a42d..102b6e3 100644
--- a/src/isodate/tzinfo.py
+++ b/src/isodate/tzinfo.py
@@ -1,8 +1,8 @@
-'''
+"""
This module provides some datetime.tzinfo implementations.
All those classes are taken from the Python documentation.
-'''
+"""
from datetime import timedelta, tzinfo
import time
@@ -11,35 +11,35 @@ ZERO = timedelta(0)
class Utc(tzinfo):
- '''UTC
+ """UTC
Universal time coordinated time zone.
- '''
+ """
def utcoffset(self, dt):
- '''
+ """
Return offset from UTC in minutes east of UTC, which is ZERO for UTC.
- '''
+ """
return ZERO
def tzname(self, dt):
- '''
+ """
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 ZERO
def __reduce__(self):
- '''
+ """
When unpickling a Utc object, return the default instance below, UTC.
- '''
+ """
return _Utc, ()
@@ -48,53 +48,53 @@ UTC = Utc()
def _Utc():
- '''
+ """
Helper function for unpickling a Utc object.
- '''
+ """
return UTC
class FixedOffset(tzinfo):
- '''
+ """
A class building tzinfo objects for fixed-offset time zones.
Note that FixedOffset(0, 0, "UTC") or FixedOffset() is a different way to
build a UTC tzinfo object.
- '''
+ """
def __init__(self, offset_hours=0, offset_minutes=0, name="UTC"):
- '''
+ """
Initialise an instance with time offset and name.
The time offset should be positive for time zones east of UTC
and negate for time zones west of UTC.
- '''
+ """
self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes)
self.__name = name
def utcoffset(self, dt):
- '''
+ """
Return offset from UTC in minutes of UTC.
- '''
+ """
return self.__offset
def tzname(self, dt):
- '''
+ """
Return the time zone name corresponding to the datetime object dt, as a
string.
- '''
+ """
return self.__name
def dst(self, dt):
- '''
+ """
Return the daylight saving time (DST) adjustment, in minutes east of
UTC.
- '''
+ """
return ZERO
def __repr__(self):
- '''
+ """
Return nicely formatted repr string.
- '''
+ """
return "<FixedOffset %r>" % self.__name
@@ -117,37 +117,45 @@ class LocalTimezone(tzinfo):
"""
def utcoffset(self, dt):
- '''
+ """
Return offset from UTC in minutes of UTC.
- '''
+ """
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
- '''
+ """
Return daylight saving offset.
- '''
+ """
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
- '''
+ """
Return the time zone name corresponding to the datetime object dt, as a
string.
- '''
+ """
return time.tzname[self._isdst(dt)]
def _isdst(self, dt):
- '''
+ """
Returns true if DST is active for given datetime object dt.
- '''
- tt = (dt.year, dt.month, dt.day,
- dt.hour, dt.minute, dt.second,
- dt.weekday(), 0, -1)
+ """
+ tt = (
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.weekday(),
+ 0,
+ -1,
+ )
stamp = time.mktime(tt)
tt = time.localtime(stamp)
return tt.tm_isdst > 0