Skip to content

fix(gui): resolve date and date_range day loss in negative UTC offsets (#2879)#2881

Open
Marcelluxx wants to merge 1 commit into
Avaiga:developfrom
Marcelluxx:bug/date-date-range-timezone-offset-2879
Open

fix(gui): resolve date and date_range day loss in negative UTC offsets (#2879)#2881
Marcelluxx wants to merge 1 commit into
Avaiga:developfrom
Marcelluxx:bug/date-date-range-timezone-offset-2879

Conversation

@Marcelluxx

Copy link
Copy Markdown
  • Avoid direct in-place mutation of Date objects by cloning them inside getTimeZonedDate
  • Avoid applying timezone offset adjustments to date-only pickers (withTime=false)
  • Parse date-only ISO strings (YYYY-MM-DD) as local midnight instead of UTC midnight in getDateTime
  • Add unit tests verifying robust local date-only parsing and formatting
  • Fix missing withTime prop in DateSelector.spec.tsx test

What type of PR is this? (Check all that apply)

  • 🛠 Refactor
  • ✨ Feature
  • 🐛 Bug Fix
  • ⚡ Optimization
  • 📝 Documentation Update

Description

This PR fixes a critical bug where tgb.date and tgb.date_range with with_time=False lose exactly one day every time a new date is selected if the browser is in a timezone with a negative UTC offset (e.g., America/Los_Angeles which is UTC-0700).

🔍 Root Cause

  1. ECMAScript ISO Date Parsing: In getDateTime(), date-only ISO strings (like "2025-06-06") were parsed using new Date(value). The JS standard specifies that date-only ISO strings should be parsed as UTC midnight. In a negative timezone, UTC midnight translates to the previous day in local time (e.g. June 5th 17:00:00), leading to a day-loss on initial rendering.
  2. In-place State Mutation & Timezone Offsetting: In getTimeZonedDate(), timezone adjustments directly mutated the Date object in-place (const newDate = d), polluting the React component state. Additionally, date-only values were being shifted by timezone offset hours, leading to cumulative day-loss on updates.

🛠️ Proposed Changes

  • Clone Date Instances: Updated getTimeZonedDate() to clone the incoming date (const newDate = new Date(d)) to protect React state against side-effects.
  • Skip Timezone Adjustments for Date-Only Pickers: Bypassed timezone addition/subtraction when withTime is false inside getTimeZonedDate(). Local hours and minutes are now cleanly set to local midnight (00:00), ensuring the local date components match exactly what the user selected.
  • Local Midnight Parsing: Configured getDateTime() to detect date-only strings (matching ^(\d{4})-(\d{2})-(\d{2})) and construct the Date object using local date components (new Date(year, monthIndex, day)) instead of UTC midnight.
  • Spec Improvements:
    • Added a missing withTime={true} prop to a test inside DateSelector.spec.tsx that asserts time formatting.
    • Added 3 new unit tests to index.spec.ts validating robust date-only parsing, formatting, and clone/non-mutation behaviors.

Related Tickets & Documents


How to reproduce the issue

  1. Set your machine's system time or browser timezone to a negative offset (e.g. America/New_York or America/Los_Angeles).
  2. Run a Taipy application with a date selector: <tgb:date d="{date_var}" with_time="False"/>
  3. Select any date (e.g., 06/06/2025). The display will immediately slip back and show 06/05/2025.

Backporting

This change should be backported to:

  • 3.0
  • 3.1
  • 4.0
  • develop

Checklist

We encourage keeping the code coverage percentage at 80% or above.

  • ✅ This solution meets the acceptance criteria of the related issue.
  • 📝 The related issue checklist is completed.
  • 🧪 This PR includes unit tests for the developed code.
  • 🔄 End-to-End tests have been added or updated.
    If not, explain why: No E2E UI-level automation tests were added because the bug and its fix reside in core client-side parsing utility code, which is 100% covered and verified by the new unit tests in index.spec.ts and component tests in DateSelector.spec.tsx.
  • 📚 The documentation has been updated, or a dedicated issue has been created.
    If not, explain why: The public API, properties, and configuration syntax remain unchanged; this is an internal logic fix.
  • 📌 The release notes have been updated.
    If not, explain why: Standard internal bugfix; will be logged automatically by maintainers on merge.

- Avoid direct in-place mutation of Date objects by cloning them inside getTimeZonedDate
- Avoid applying timezone offset adjustments to date-only pickers (withTime=false)
- Parse date-only ISO strings (YYYY-MM-DD) as local midnight instead of UTC midnight in getDateTime
- Add unit tests verifying robust local date-only parsing and formatting
- Fix missing withTime prop in DateSelector.spec.tsx test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 BUG] date and date_range issue when browser timezone is < +00

1 participant