+ def test_go_vectors_valid_ber(self):
+ for data in ((
+ b"20100102030405+0607",
+ b"20100102030405-0607",
+ )):
+ GeneralizedTime(data, ctx={"bered": True})
+
+ def test_utc_offsets(self):
+ """Some know equal UTC offsets
+ """
+ dts = [
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+ for data in (
+ "200101011830Z",
+ "200101012230+04",
+ "200101011130-0700",
+ "200101011500-03:30",
+ )
+ ]
+ self.assertEqual(dts[0], dts[1])
+ self.assertEqual(dts[0], dts[2])
+ self.assertEqual(dts[0], dts[3])
+
+ @settings(max_examples=LONG_TEST_MAX_EXAMPLES)
+ @given(data_strategy())
+ def test_valid_ber(self, d):
+ year = d.draw(integers(min_value=2, max_value=9999))
+ month = d.draw(integers(min_value=1, max_value=12))
+ day = d.draw(integers(min_value=1, max_value=28))
+ hours = d.draw(integers(min_value=0, max_value=23))
+ data = "%04d%02d%02d%02d" % (year, month, day, hours)
+ dt = datetime(year, month, day, hours)
+ fractions_sign = d.draw(sampled_from(" ,."))
+ fractions = None
+ if fractions_sign != " ":
+ fractions = random()
+ if d.draw(booleans()):
+ minutes = d.draw(integers(min_value=0, max_value=59))
+ data += "%02d" % minutes
+ dt += timedelta(seconds=60 * minutes)
+ if d.draw(booleans()):
+ seconds = d.draw(integers(min_value=0, max_value=59))
+ data += "%02d" % seconds
+ dt += timedelta(seconds=seconds)
+ if fractions is not None:
+ dt += timedelta(microseconds=10**6 * fractions)
+ elif fractions is not None:
+ dt += timedelta(seconds=60 * fractions)
+ elif fractions is not None:
+ dt += timedelta(seconds=3600 * fractions)
+ if fractions is not None:
+ data += fractions_sign + str(fractions)[2:]
+ if d.draw(booleans()):
+ data += "Z"
+ elif d.draw(booleans()):
+ offset_hour = d.draw(integers(min_value=0, max_value=13))
+ sign = 1
+ if d.draw(booleans()):
+ data += "-"
+ sign = -1
+ else:
+ data += "+"
+ dt -= timedelta(seconds=sign * 3600 * offset_hour)
+ data += "%02d" % offset_hour
+ minutes_separator = d.draw(sampled_from((None, "", ":")))
+ if minutes_separator is not None:
+ offset_minute = d.draw(integers(min_value=0, max_value=59))
+ dt -= timedelta(seconds=sign * 60 * offset_minute)
+ data += "%s%02d" % (minutes_separator, offset_minute)
+ data = data.encode("ascii")
+ data_der = GeneralizedTime.tag_default + len_encode(len(data)) + data
+ try:
+ GeneralizedTime().decod(data_der)
+ except DecodeError:
+ dered = False
+ else:
+ dered = True
+ obj = GeneralizedTime().decod(data_der, ctx={"bered": True})
+ if dt.year > 1970:
+ self.assertEqual(
+ mktime(obj.todatetime().timetuple()),
+ mktime(dt.timetuple()),
+ )
+ else:
+ try:
+ obj.todatetime().timestamp()
+ except:
+ pass
+ else:
+ self.assertEqual(obj.todatetime().timestamp(), dt.timestamp())
+ self.assertEqual(obj.ber_encoded, not dered)
+ self.assertEqual(obj.bered, not dered)
+ self.assertEqual(obj.ber_raw, None if dered else data)
+ self.assertEqual(obj.encode() == data_der, dered)
+ repr(obj)
+ bytes(obj)
+ str(obj)
+
+ def test_invalid_ber(self):
+ for data in ((
+ # "00010203040506.07",
+ "-0010203040506.07",
+ "0001-203040506.07",
+ "000102-3040506.07",
+ "00010203-40506.07",
+ "0001020304-506.07",
+ "000102030405-6.07",
+ "00010203040506.-7",
+ "+0010203040506.07",
+ "0001+203040506.07",
+ "000102+3040506.07",
+ "00010203+40506.07",
+ "0001020304+506.07",
+ "000102030405+6.07",
+ "00010203040506.+7",
+ " 0010203040506.07",
+ "0001 203040506.07",
+ "000102 3040506.07",
+ "00010203 40506.07",
+ "0001020304 506.07",
+ "000102030405 6.07",
+ "00010203040506. 7",
+ "001 0203040506.07",
+ "00012 03040506.07",
+ "0001023 040506.07",
+ "000102034 0506.07",
+ "00010203045 06.07",
+ "0001020304056 .07",
+ "00010203040506.7 ",
+ "00010203040506.",
+ "0001020304050607",
+
+ "-0010203040506",
+ "0001-203040506",
+ "000102-3040506",
+ "00010203-40506",
+ "0001020304-506",
+ "000102030405-6",
+ "0001+203040506",
+ "000102+3040506",
+ "00010203+40506",
+ "0001020304+506",
+ "000102030405+6",
+ " 0010203040506",
+ "0001 203040506",
+ "000102 3040506",
+ "00010203 40506",
+ "0001020304 506",
+ "000102030405 6",
+ "001 0203040506",
+ "00012 03040506",
+ "0001023 040506",
+ "000102034 0506",
+ "00010203045 06",
+ "0001020304056 ",
+
+ "-00102030405.07",
+ "0001-2030405.07",
+ "000102-30405.07",
+ "00010203-405.07",
+ "0001020304-5.07",
+ "000102030405.-7",
+ "+00102030405.07",
+ "0001+2030405.07",
+ "00010203+405.07",
+ "0001020304+5.07",
+ "000102030405.+7",
+ " 00102030405.07",
+ "0001 2030405.07",
+ "000102 30405.07",
+ "00010203 405.07",
+ "0001020304 5.07",
+ "000102030405. 7",
+ "001 02030405.07",
+ "00012 030405.07",
+ "0001023 0405.07",
+ "000102034 05.07",
+ "00010203045 .07",
+ "000102030405.7 ",
+ "000102030405.",
+
+ "-001020304.07",
+ "0001-20304.07",
+ "000102-304.07",
+ "00010203-4.07",
+ "0001020304.-7",
+ "+001020304.07",
+ "0001+20304.07",
+ "00010203+4.07",
+ "0001020304.+7",
+ " 001020304.07",
+ "0001 20304.07",
+ "000102 304.07",
+ "00010203 4.07",
+ "0001020304. 7",
+ "001 020304.07",
+ "00012 0304.07",
+ "0001023 04.07",
+ "000102034 .07",
+ "0001020304.7 ",
+ "0001020304.",
+
+ "00010203",
+ "00010203040506Y",
+ "0001010100+0001",
+ "0001010100+00:01",
+ "0001010100+01",
+
+ "00010203040506.07+15",
+ "00010203040506.07-15",
+ "00010203040506.07+14:60",
+ "00010203040506.07+1460",
+ "00010203040506.07-1460",
+ "00010203040506.07+00:60",
+ "00010203040506.07-00:60",
+
+ "00010203040506+15",
+ "00010203040506-15",
+ "00010203040506+14:60",
+ "00010203040506+1460",
+ "00010203040506-1460",
+ "00010203040506+00:60",
+ "00010203040506-00:60",
+
+ "0001020304050.07",
+ "00010203040.07",
+ "000102030.07",
+ "0001020304050",
+ "00010203040",
+ "000102030",
+ )):
+ with self.assertRaises(DecodeError):
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+ data = data.replace(".", ",")
+ with self.assertRaises(DecodeError):
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+
+ @given(
+ binary(
+ min_size=(LEN_YYYYMMDDHHMMSSZ - 1) // 2,