Fix date filtering for all-day entries across timezones - #2392
Merged
Merged
Conversation
Time based filters showed entries of the neighbouring day whenever the device timezone was not UTC: the day boundaries were calculated with DateTimeUtils.getTodayAsLong(), which returns midnight UTC. That is the correct representation for all-day entries (they are stored as midnight UTC), but entries with a time are stored as the epoch millis of the actual instant, so e.g. "Started today" covered "today 00:00 UTC" until "tomorrow 00:00 UTC" - in a +11:30 timezone that is local 11:30 today until 11:30 tomorrow. The day boundaries are now calculated for both cases separately and the query picks the matching one via the timezone column of the respective date, so all-day entries keep being compared in UTC while all other entries are compared against the beginning of the local day. This applies to the today/tomorrow/within 7 days filters, the in past/future filters (all-day entries of today are now neither), the date range and day range filters (the pickers deliver midnight UTC as well) and to the lookup of the next recurring instance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Am92mRS8fz3WKPdBSNdVKS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes date filtering logic to correctly handle all-day entries across different timezones. Previously, filtering by date ranges would incorrectly include entries from neighboring days when the system timezone was not UTC, since all-day entries are stored as midnight UTC while timed entries are stored as epoch milliseconds.
Key Changes
Added timezone-aware filtering methods in
ICal4List:getDayRangeFilter(): Generates SQL CASE statements that apply different boundary calculations for all-day entries (UTC-based) vs timed entries (local timezone-based)getBeforeNowFilter()andgetAfterNowFilter(): Handle "past" and "future" filters with timezone awarenessUpdated all date filtering queries to use the new methods:
BETWEENclauses with timezone-aware filtering for start date, due date, and completed date filtersAdded utility functions in
DateTimeUtils:getStartOfDayUTCAsLong(): Returns midnight UTC for a given date (for all-day entries)getStartOfDayLocalAsLong(): Returns midnight in local timezone (for timed entries)getLocalDateFromUTCMidnight(): Converts UTC midnight epoch to LocalDateAdded comprehensive test coverage in
ICal4ListTest:Implementation Details
The core issue is that jtx stores:
When filtering by day boundaries, using UTC-based calculations for both types causes entries to slip into adjacent days on non-UTC timezones. The solution uses SQL CASE statements to apply the correct boundary calculation based on the timezone column value.
https://claude.ai/code/session_01Am92mRS8fz3WKPdBSNdVKS