Skip to content

A month or year Shift of a short LocalDateRange can return Empty; R28 says Shift keeps the shape #259

Closed

Description

@CaffeinatedCoder

Problem

#223's month rule (PR #238) shifts the exclusive end, so a short LocalDateRange ending on the 28th–31st can shift to Empty:

  • [2024-02-28,2024-02-28].Shift(Period.FromYears(1)) is Empty: the start goes to 2025-02-28, and the end goes 02-29 → 2025-02-28 → minus one day → 02-27.
  • [2024-03-30,2024-03-30].Shift(P1M), [2024-01-29].Shift(P1M) and [2023-12-30].Shift(P-1M) are Empty too.

A sweep of every day from 2023-12 to 2025-03, lengths 0–35, steps ±1M, ±1Y and 13M, found 33 such cases. PostgreSQL gives the same (daterange(d + interval, (d+1) + interval) is empty), and so does LocalDateTimeRange on [d,d+1). But claim R28 (docs/ranges.md#move-or-widen-a-range) says "Both keep the shape", and the docs mention Empty only for a negative Expand. #238's tests sweep whole months and quarters only. Found by the final pre-release analysis on add665c (pass A).

Decision (maintainer, 2026-10-19)

Keep the rule, since it is PostgreSQL's answer and LocalDateTimeRange's, and document it. A month or year Shift of a short range can return Empty.

Done when

R28 and R31 and docs/ranges.md say when Shift returns Empty. A test holds the sweep's representative cases ([2024-02-28,2024-02-28].Shift(P1Y) is Empty, and so on) for LocalDateRange, DateRange if it has period shifts, and LocalDateTimeRange.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/rangesRange unions, variants and the shape enginesdocumentationImprovements or additions to documentationpackage/coreAffects CodoMetis.ValueRangespackage/nodatimeAffects CodoMetis.ValueRanges.NodaTime

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions