Skip to content

Commit 72c85cd

Browse files
committed
BUG: honor ambiguous/nonexistent for tz-aware endpoints in date_range
1 parent cc40732 commit 72c85cd

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

pandas/core/arrays/datetimes.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,14 @@ def _generate_range(
456456
end = _maybe_localize_point(end, freq, tz, ambiguous, nonexistent)
457457

458458
if freq is not None:
459-
# We break Day arithmetic (fixed 24 hour) here and opt for
460-
# Day to mean calendar day (23/24/25 hour). Therefore, strip
461-
# tz info from start and day to avoid DST arithmetic
462-
if isinstance(freq, Day):
463-
if start is not None:
459+
# Offset handling:
460+
# Ticks (fixed-duration like hours/minutes): keep tz; do absolute-time math.
461+
# Other calendar offsets: drop tz; do naive wall time; localize once later
462+
# so `ambiguous`/`nonexistent` are applied correctly.
463+
if not isinstance(freq, Tick):
464+
if start is not None and start.tz is not None:
464465
start = start.tz_localize(None)
465-
if end is not None:
466+
if end is not None and end.tz is not None:
466467
end = end.tz_localize(None)
467468

468469
if isinstance(freq, (Tick, Day)):

pandas/tests/indexes/datetimes/test_date_range.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,3 +1740,23 @@ def test_date_range_negative_freq_year_end_inbounds(self, unit):
17401740
freq="-1YE",
17411741
)
17421742
tm.assert_index_equal(rng, exp)
1743+
1744+
def test_date_range_tzaware_endpoints_accept_ambiguous(self):
1745+
# With tz-aware endpoints and a calendar offset (MS),
1746+
# date_range should accept `ambiguous=True` and produce
1747+
# the same result as passing tz explicitly with naive endpoints.
1748+
start = Timestamp("1916-08-01", tz="Europe/Oslo")
1749+
end = Timestamp("1916-12-01", tz="Europe/Oslo")
1750+
res = date_range(start, end, freq="MS", ambiguous=True)
1751+
exp = date_range(
1752+
"1916-08-01", "1916-12-01", freq="MS", tz="Europe/Oslo", ambiguous=True
1753+
)
1754+
tm.assert_index_equal(res, exp)
1755+
1756+
def test_date_range_tzaware_endpoints_raise_ambiguous_raises_by_default(self):
1757+
# By default (`ambiguous="raise"`), an ambiguous DST transition
1758+
# should raise instead of guessing.
1759+
start = Timestamp("1916-08-01", tz="Europe/Oslo")
1760+
end = Timestamp("1916-12-01", tz="Europe/Oslo")
1761+
with pytest.raises(ValueError, match="Cannot infer dst time"):
1762+
date_range(start, end, freq="MS")

0 commit comments

Comments
 (0)