Skip to content

fix: align naive datetimes independent of the local UTC offset - #1146

Open
charanteja25 wants to merge 1 commit into
OpenSTEF:mainfrom
charanteja25:fix/align-datetime-naive-local-offset
Open

charanteja25 wants to merge 1 commit into
OpenSTEF:mainfrom
charanteja25:fix/align-datetime-naive-local-offset

Conversation

@charanteja25

@charanteja25 charanteja25 commented Oct 15, 2026 •

Copy link
Copy Markdown

Is your feature request related to a problem?

Yes, a bug. align_datetime (openstef_core.utils.datetime) aligns a naive datetime with datetime.timestamp(). For a naive datetime, this call applies the local UTC offset of the machine. If that offset is not a multiple of the interval, the result is wrong. Example: UTC+05:30 (India) and a one-hour interval.

Reproduce:

TZ="IST-5:30" python -c "
from datetime import datetime, timedelta
from openstef_core.utils.datetime import align_datetime
print(align_datetime(datetime(2020, 1, 1, 10, 45), timedelta(hours=1), 'floor'))
"

Expected 2020-01-01 10:00:00, actual 2020-01-01 10:30:00. With TZ=UTC the result is correct.

Impact:

  • 5 existing tests fail on a machine in an India time zone and pass with TZ=UTC: 4 in test_datetime.py (test_align_datetime_naive) and test_run_returns_evaluation_report in openstef-beam.
  • align_datetime is used by the evaluation window iterator (window_iterators.py). With naive datetimes, window boundaries can shift by 30 minutes in such time zones, and the error is silent.
  • The same applies to other zones with a non-whole-hour offset (for example Nepal, parts of Australia, Newfoundland).

Describe the solution you'd like

For naive datetimes, align with timedelta arithmetic relative to a naive epoch (datetime(1970, 1, 1)). Aware datetimes stay unchanged. A new regression test runs with the process timezone set to UTC+05:30 and fails without the fix.

Describe alternatives you've considered

  • Convert naive datetimes to UTC first: this needs an assumption about the zone of a naive value, and the library does not make that assumption.
  • Reject naive datetimes: this is the direction of [OpenSTEF 4.0] Improved timezone handling/verifications #715, but it is a breaking change and needs a decision from the maintainers.

Affected package(s)

  • openstef-core
  • openstef-beam (uses the function, no code change)
  • openstef-models
  • openstef-foundation-models
  • openstef-meta
  • docs

Would this require breaking changes to the public API?

No. Only naive datetimes at non-whole-hour offsets give a different (correct) result.

Additional context

Related to #715 (timezone robustness). This is a concrete case of a silent problem with naive datetimes.

Question for the review: for aware datetimes, the function aligns on UTC epoch boundaries, not on local wall-clock boundaries. For example, 10:45 in a +05:30 zone with a one-hour interval floors to 09:30 local time, not 10:00. I did not change this, because it may be intended. Is it?

Checks:

  • poe all --check passes on my machine in the +5:30 time zone, without TZ=UTC: 1131 tests and 110 doctests passed. The 5 failures above are gone.
  • The new test fails without the fix and passes with it.
  • Commit is signed off (DCO).

align_datetime used datetime.timestamp() for naive datetimes. That call applies the local UTC offset of the machine, so alignment to an interval was wrong when the offset is not a multiple of the interval (for example UTC+05:30 and a one-hour interval). Naive datetimes are now aligned with timedelta arithmetic relative to a naive epoch. Aware datetimes are unchanged.

Add a regression test that runs with the process timezone set to UTC+05:30.

Signed-off-by: charanteja25 <charanteja.teja25@gmail.com>
@charanteja25
charanteja25 requested a review from a team October 15, 2026 12:07
@github-actions github-actions Bot added the fix Something isn't working label Oct 15, 2026

This branch has not been deployed

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

Labels

fix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant