Skip to content

fix(arrow-cast): truncate Timestamp to Date64 casts to whole days - #11632

Merged
Jefffrey merged 1 commit into
apache:mainfrom
ump45nose:fix/timestamp-to-date64-whole-days
Oct 18, 2026
Merged

Jefffrey merged 1 commit into
apache:mainfrom
ump45nose:fix/timestamp-to-date64-whole-days

Conversation

@ump45nose

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

Timestamp -> Date64 kept the time of day, so the result could hold values that are not multiples of 86_400_000, which the Date64 docs say are invalid. Timestamp -> Date32 already truncates to the date, so the two casts disagreed.

What changes are included in this PR?

The four Timestamp -> Date64 arms now go through a new timestamp_to_date64 helper next to timestamp_to_date32, using the same rules:

  • Without a timezone, the value is floored to the start of its UTC day, so timestamps before the epoch land on the previous day. Flooring i64::MIN milliseconds to a day overflows, so that case is null for a safe cast and an error otherwise, the same as the existing seconds overflow.
  • With a timezone, the result is the local date, which answers the question @mbutrovich raised on the issue: for -05:00, 1970-01-01T00:00:01Z becomes 1969-12-31. In other words, cast(ts, Date64) now equals cast(cast(ts, Date32), Date64). I went with this because it matches Date32; if you'd prefer flooring the UTC value for zoned timestamps instead, that's an easy change.

Are these changes tested?

Yes. test_cast_timestamp_to_date64 now expects whole days, and a new test_cast_timestamp_to_date64_whole_days covers all four units (including a timestamp just before the epoch), the timezone case checked against the Date32 path, and the overflow case.

Are there any significant user-facing changes?

Yes, the cast returns different values than before: any Timestamp -> Date64 cast that used to keep a time of day now returns midnight, and zoned timestamps return the local date. Values that were outside chrono's date range in a zoned array now become null (or an error for a non-safe cast), as they already do for Date32.

AI disclosure: I used an AI coding assistant to write the change, tests, and this description. I reviewed the diff and the test expectations.

@github-actions github-actions Bot added arrow-kernels Crates that transform arrow data (e.g. compute, cast) bug labels Oct 16, 2026
@Jefffrey
Jefffrey added this pull request to the merge queue Oct 18, 2026
Merged via the queue into apache:main with commit 534da94 Oct 18, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow-kernels Crates that transform arrow data (e.g. compute, cast) bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Casting Timestamp to Date64 keeps the time of day, producing invalid Date64 values

2 participants