diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 94ee1d5..96487db 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false # Changed to false to see all failures matrix: os: [ ubuntu-latest, windows-latest, macos-latest, ubuntu-24.04-arm ] - python-version: [ "3.8","3.9","3.10", "3.11","3.12", "3.13" ] # ToDo: add support for 3.14 when it's available in GitHub Actions + python-version: [ "3.8","3.9","3.10", "3.11","3.12", "3.13", "3.14" ] # ToDo: add support for 3.14 when it's available in GitHub Actions steps: - uses: actions/checkout@v4 diff --git a/setup.py b/setup.py index 6a3f247..b2647aa 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ __author__ = 'ASU' # Bump up this version -VERSION = '0.2.12' +VERSION = '0.2.13' basedir = path.abspath(path.dirname(__file__)) diff --git a/tests/test_ts.py b/tests/test_ts.py index e90885c..5479613 100644 --- a/tests/test_ts.py +++ b/tests/test_ts.py @@ -1155,6 +1155,15 @@ class Test_iTSns(TestCase): def test_from_iso(self): run_test_from_iso(self, iTSns) + def test_regression_itsns_constructor_vs_from_iso(self): + """Test that iTSns() and iTSns.from_iso() produce the same result""" + date_str = "2025-11-02T13:45:14.012345678Z" + result1 = iTSns(date_str) + result2 = iTSns.from_iso(date_str) + self.assertEqual(result1, result2) + self.assertEqual( 1762091114012345678, int(result1)) + self.assertEqual(result2.isoformat(), date_str) + def test_error_message_regression(self): a = "invalid-timestamp" with self.assertRaises(ValueError) as e: diff --git a/tsx/ts.py b/tsx/ts.py index 71a20a5..4151c95 100644 --- a/tsx/ts.py +++ b/tsx/ts.py @@ -1079,6 +1079,18 @@ def now(cls) -> Self: tns = time_ns() return cls(tns) + @classmethod + def from_iso(cls, ts: str, utc: bool = True) -> Self: + """ + Attention: if timestamp has TZ info, it will ignore the utc parameter + This method exists because dateutil.parser is too generic and wrongly parses basic ISO date like `20210101` + It will allow any of ISO-8601 formats, but will not allow any other formats + """ + if len(ts) <= 14: # has <= seconds precision + return super().from_iso(ts, utc) + i = cls.ns_timestamp_from_iso(ts, utc) + return cls(i) + def as_nsec(self) -> "iTSns": return self