Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyiceberg/utils/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def timestamptz_to_nanos(timestamptz_str: str) -> int:
ms_str = match.group(2) if match.group(2) else ""
timestamptz_str_without_ns_str = match.group(1) + ms_str + match.group(4)
return datetime_to_nanos(datetime.fromisoformat(timestamptz_str_without_ns_str)) + int(ns_str)
if ISO_TIMESTAMPTZ_NANO.fullmatch(timestamptz_str):
if ISO_TIMESTAMP_NANO.fullmatch(timestamptz_str):
# When we can match a timestamp without a zone, we can give a more specific error
raise ValueError(f"Missing zone offset: {timestamptz_str} (must be ISO-8601)")
raise ValueError(f"Invalid timestamp with zone: {timestamptz_str} (must be ISO-8601)")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We could add test cases for Invalid timestamp with zone in this method and Invalid timestamp without zone in timestamp_to_nanos as a follow-up.

Expand Down
10 changes: 10 additions & 0 deletions tests/utils/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ def test_timestamptz_to_nanos(timestamp: str, nanos: int) -> None:
assert nanos == timestamptz_to_nanos(timestamp)


def test_timestamptz_to_nanos_missing_zone_offset() -> None:
with pytest.raises(ValueError, match="Missing zone offset: 2025-02-23T20:21:44.375612001"):
timestamptz_to_nanos("2025-02-23T20:21:44.375612001")


def test_timestamp_to_nanos_unexpected_zone_offset() -> None:
with pytest.raises(ValueError, match="Zone offset provided, but not expected: 2025-02-23T16:21:44.375612001-04:00"):
timestamp_to_nanos("2025-02-23T16:21:44.375612001-04:00")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd move this test under test_timestamp_to_nanos so related timestamp_to_nanos tests stay close together.



@pytest.mark.parametrize("nanos, micros", [(1510871468000001001, 1510871468000001), (-1510871468000001001, -1510871468000002)])
def test_nanos_to_micros(nanos: int, micros: int) -> None:
assert micros == nanos_to_micros(nanos)
Expand Down