diff --git a/CHANGELOG.md b/CHANGELOG.md index cf07a8d..a7ff391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.1] - 2024-22-05 + +### Added + +- Super basic unittests for `instant_to_datetime` and `timestamp_to_datetime` + cause there was a super dumb error which those would have caught + + +### Changed + +- The unittest for `any_to_datetime` to account for "instant" + + +### Fixed + +- The `any_to_datetime` call where it's accidentally casting "instants" to + "timestamps" + + ## [1.2.0] - 2024-22-05 ### Added @@ -15,14 +34,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 UNIX Epoch as a float) that work even on Windows when the built in `datetime.timestamp()` and `datetime.fromtimestamp()` methods fail for negative values and more -- Methods for casting between Datetime and "instance" (number of milliseconds +- Methods for casting between Datetime and "instant" (number of milliseconds since UNIX Epoch as an int) ### Changed - How `any_to_datetime` handles "ambiguous" numeric values when deciding between - "timestamp", "instance" and "filetime" + "timestamp", "instant" and "filetime" - How `any_to_datetime` handles strings such that if a given string is a simple int or float, it's cast and treated as such diff --git a/ccptools/__init__.py b/ccptools/__init__.py index 3d201c6..c406d3b 100644 --- a/ccptools/__init__.py +++ b/ccptools/__init__.py @@ -1,4 +1,4 @@ -__version__ = '1.2.0' +__version__ = '1.2.1' __author__ = 'Thordur Matthiasson ' __license__ = 'MIT License' diff --git a/ccptools/dtu/casting/_any.py b/ccptools/dtu/casting/_any.py index 91893a0..5ba8ecd 100644 --- a/ccptools/dtu/casting/_any.py +++ b/ccptools/dtu/casting/_any.py @@ -90,7 +90,7 @@ def any_to_datetime(temporal_object: T_TEMPORAL_VALUE, # This range means that the number, if treated as an instant, # represents a datetime within 1000 years to/from now so it's the # second most likely bet! - return timestamp_to_datetime(temporal_object) + return instant_to_datetime(temporal_object) # This number is so large that it's most likely a filetime! return filetime_to_datetime(temporal_object) diff --git a/tests/datetimeutils/test_datetimeutils.py b/tests/datetimeutils/test_datetimeutils.py index 5cdba79..553dda4 100644 --- a/tests/datetimeutils/test_datetimeutils.py +++ b/tests/datetimeutils/test_datetimeutils.py @@ -20,6 +20,7 @@ def assertDefault(value): assertSame(119445914047564820, (1979, 7, 6, 14, 3, 24, 756482)) assertSame(300117804, (1979, 7, 6, 14, 3, 24)) assertSame(300117804.321321, (1979, 7, 6, 14, 3, 24, 321321)) + assertSame(300117804321.321, (1979, 7, 6, 14, 3, 24, 321321)) assertSame(1570875489.134, (2019, 10, 12, 10, 18, 9, 134000)) assertSame(None, None) diff --git a/tests/datetimeutils/test_instant.py b/tests/datetimeutils/test_instant.py index d45047b..eef2c6a 100644 --- a/tests/datetimeutils/test_instant.py +++ b/tests/datetimeutils/test_instant.py @@ -3,7 +3,17 @@ from ccptools.dtu.casting import * +def _millisec_resolution(dt: Datetime) -> Datetime: + return dt.replace(microsecond=int(dt.microsecond / 1000.)*1000) + + class TestInstant(unittest.TestCase): def test_instant_to_datetime(self): _dt = Datetime(2024, 5, 22, 10, 37, 54, 123000) - self.assertEqual(_dt, instant_to_datetime(1716374274123)) + self.assertEqual(_dt, _millisec_resolution(instant_to_datetime(1716374274123))) + + _dt = Datetime(1024, 5, 22, 10, 37, 54, 987000) + self.assertEqual(_dt, _millisec_resolution(instant_to_datetime(-29840620925013))) + + _dt = Datetime(3024, 5, 22, 10, 37, 54, 123000) + self.assertEqual(_dt, _millisec_resolution(instant_to_datetime(33273283074123))) diff --git a/tests/datetimeutils/test_timestamp.py b/tests/datetimeutils/test_timestamp.py new file mode 100644 index 0000000..55ee28f --- /dev/null +++ b/tests/datetimeutils/test_timestamp.py @@ -0,0 +1,19 @@ +import unittest +from ccptools.dtu.structs import * +from ccptools.dtu.casting import * + + +def _10_microsec_resolution(dt: Datetime) -> Datetime: + return dt.replace(microsecond=int(dt.microsecond / 10.)*10) + + +class TestInstant(unittest.TestCase): + def test_instant_to_datetime(self): + _dt = Datetime(2024, 5, 22, 10, 37, 54, 123456) + self.assertEqual(_10_microsec_resolution(_dt), _10_microsec_resolution(timestamp_to_datetime(1716374274.123456))) + + _dt = Datetime(1024, 5, 22, 10, 37, 54, 987654) + self.assertEqual(_10_microsec_resolution(_dt), _10_microsec_resolution(timestamp_to_datetime(-29840620925.012344))) + + _dt = Datetime(3024, 5, 22, 10, 37, 54, 123456) + self.assertEqual(_10_microsec_resolution(_dt), _10_microsec_resolution(timestamp_to_datetime(33273283074.123456)))