Skip to content

Fix naturalday/naturaldate wrong answer for tz-aware datetimes#296

Open
Fridayai700 wants to merge 2 commits intopython-humanize:mainfrom
Fridayai700:fix-naturaldate-timezone
Open

Fix naturalday/naturaldate wrong answer for tz-aware datetimes#296
Fridayai700 wants to merge 2 commits intopython-humanize:mainfrom
Fridayai700:fix-naturaldate-timezone

Conversation

@Fridayai700
Copy link

Summary

When a tz-aware datetime is passed, naturalday() and naturaldate() extract the date in the value's timezone (via dt.date(value.year, value.month, value.day)) but compare it with dt.date.today() which uses system local time. This produces wrong results when the value's timezone differs from the system timezone.

Example from the issue: When the system is in UTC and it's Oct 15 23:00 UTC (Oct 16 10:00 AEDT), calling naturaldate() with an AEDT datetime on Oct 16 should return "today" (both dates are Oct 16 in AEDT), but instead returns "tomorrow" because date.today() returns Oct 15 (the system's UTC date).

Fix

Capture the value's tzinfo before converting to a plain date. If a timezone is present, derive "today" via datetime.now(tzinfo).date() so both dates are in the same timezone.

Test plan

  • Added test_naturalday_tz_aware — tests UTC, AEDT (+11), EDT (-4), PDT (-7) against a future datetime, verifying today/tomorrow is computed relative to each timezone
  • Added test_naturaldate_tz_aware — same scenario through naturaldate()
  • All 46 time tests pass, including all existing tests (no regressions)

Fixes #152

Fridayai700 and others added 2 commits February 18, 2026 05:03
When a tz-aware datetime is passed, naturalday() and naturaldate()
extract the date in the value's timezone but compare it with
date.today() which uses system local time. This produces wrong results
when the value's timezone differs from the system timezone.

Fix: capture the value's tzinfo before converting to a plain date,
then derive "today" via datetime.now(tzinfo).date() so both dates
are in the same timezone.

Fixes python-humanize#152

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hugovk hugovk added the changelog: Fixed For any bug fixes label Feb 18, 2026
@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.53%. Comparing base (471cd9b) to head (f389383).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #296      +/-   ##
==========================================
+ Coverage   99.51%   99.53%   +0.01%     
==========================================
  Files          11       11              
  Lines         831      859      +28     
==========================================
+ Hits          827      855      +28     
  Misses          4        4              
Flag Coverage Δ
macos-latest 97.90% <100.00%> (+0.07%) ⬆️
ubuntu-latest 97.90% <100.00%> (+0.07%) ⬆️
windows-latest 96.04% <100.00%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

changelog: Fixed For any bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

naturaldate() gives the wrong answer for tz-aware datetimes

2 participants

Comments