def _parse_period(cls, value: str) -> TimePeriod: year = month = day = offset = None if value.startswith("---"): day, offset = parse_date_args(value, DateFormat.G_DAY) elif value.startswith("--"): # Bogus format --MM--, --05---05:00 if value[4:6] == "--": value = value[:4] + value[6:] if len(value) in (4, 5, 10): # fixed lengths with/out timezone month, offset = parse_date_args(value, DateFormat.G_MONTH) else: month, day, offset = parse_date_args(value, DateFormat.G_MONTH_DAY) else: end = len(value) if value.find(":") > -1: # offset end -= 6 if value[:end].rfind("-") > 3: # Minimum position for month sep year, month, offset = parse_date_args(value, DateFormat.G_YEAR_MONTH) else: year, offset = parse_date_args(value, DateFormat.G_YEAR) validate_date(0, month or 1, day or 1) return TimePeriod(year=year, month=month, day=day, offset=offset)
def test_parse_date_args_year(self): args = parse_date_args("-1970-05", "%Y-%m") self.assertEqual(-1970, next(args)) self.assertEqual(5, next(args)) self.assertIsNone(next(args, None)) args = parse_date_args("0009", "%Y") self.assertEqual(9, next(args)) args = parse_date_args("0099", "%Y") self.assertEqual(99, next(args)) args = parse_date_args("0999", "%Y") self.assertEqual(999, next(args)) args = parse_date_args("9999", "%Y") self.assertEqual(9999, next(args)) with self.assertRaises(ValueError): next(parse_date_args("09999", "%Y")) with self.assertRaises(ValueError): next(parse_date_args("00999", "%Y")) with self.assertRaises(ValueError): next(parse_date_args("00099", "%Y")) with self.assertRaises(ValueError): next(parse_date_args("00009", "%Y"))
def test_parse_date_args(self): args = parse_date_args("2002-01-02T12:14:30-01:22", "%Y-%m-%dT%H:%M:%S%z") self.assertEqual(2002, next(args)) self.assertEqual(1, next(args)) self.assertEqual(2, next(args)) self.assertEqual(12, next(args)) self.assertEqual(14, next(args)) self.assertEqual(30, next(args)) self.assertEqual(0, next(args)) self.assertEqual(-82, next(args)) self.assertIsNone(next(args, None))
def test_parse_date_args_raises_value_error(self): cases = { "2002-12-01": "%F", # Unknown var "2002-01-01": "%Y", # Mismatch format "2002-1-01": "%Y", # Minimum required digits "2002": "%Y-%M", # Run out of value "$": "%z", # Unknown timezone } for value, fmt in cases.items(): with self.assertRaises(ValueError, msg=f"{value} ({fmt})") as cm: list(parse_date_args(value, fmt)) self.assertEqual(f"String '{value}' does not match format '{fmt}'", str(cm.exception))
def test_parse_date_args_trim_input(self): args = parse_date_args("\n Z ", "%z") self.assertEqual(0, next(args)) self.assertIsNone(next(args, None))
def test_parse_date_args_optional_timezone(self): args = parse_date_args("2020", "%Y%z") self.assertEqual(2020, next(args)) self.assertIsNone(None, next(args)) self.assertIsNone(next(args, None))
def test_parse_date_args_utc_timezone(self): args = parse_date_args("Z", "%z") self.assertEqual(0, next(args)) self.assertIsNone(next(args, None))
def test_parse_date_args_microsecond(self): args = parse_date_args("55.1345", "%S") self.assertEqual(55, next(args)) self.assertEqual(134500, next(args)) self.assertIsNone(next(args, None))
def from_string(cls, string: str) -> "XmlDate": """Initialize from string with format ``%Y-%m-%dT%z``""" return XmlDate(*parse_date_args(string, DateFormat.DATE))
def from_string(cls, string: str) -> "XmlTime": """Initialize from string format ``%H:%M:%S%z``""" return XmlTime(*parse_date_args(string, DateFormat.TIME))