-
Notifications
You must be signed in to change notification settings - Fork 588
Open
Description
Description
The DatePicker component incorrectly applies timezone offsets when parsing dates with time enabled, causing the displayed time to shift by the user's timezone offset from UTC.
For example, if a user in UTC+1 timezone enters 14:00, the displayed value shifts to 15:00 after saving and reloading.
Root Cause
Two issues in frontend/js/components/DatePicker.vue:
1. dateFormat uses 'Z' (ISO 8601 with timezone)
dateFormat: (self.enableTime && self.noCalendar) ? 'H:i:S' : (self.enableTime ? 'Z' : 'Y-m-d'),The 'Z' format outputs ISO 8601 dates with timezone information, but the backend stores and returns dates without timezone info. This mismatch causes parsing issues.
2. parseDate incorrectly adds 'Z' suffix
return parse(date + 'Z', fullFormat + 'X', Date.UTC());This appends a 'Z' (UTC indicator) to dates that are actually in local time, causing the timezone offset to be applied twice.
Proposed Fix
- Change
dateFormatto use explicit format without timezone:
dateFormat: (self.enableTime && self.noCalendar) ? 'H:i:S' : (self.enableTime ? 'Y-m-d H:i:S' : 'Y-m-d'),- Simplify
parseDateto not apply UTC conversions:
parseDate: function (date, format) {
// European format: dd.MM.yyyy HH:mm:ss
if (/^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}$/.test(date)) {
// Manual parsing for European format
var parts = date.split(' ');
var datePart = parts[0].split('.');
var timePart = parts[1].split(':');
return new Date(datePart[2], datePart[1] - 1, datePart[0], timePart[0], timePart[1], timePart[2]);
}
// ... similar for other European formats
// ISO formats - date-fns v1 parse() handles these correctly
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(date)) {
return parse(date);
}
// ... etc
return new Date(date);
}Environment
- Twill version: 3.5.2
- PHP version: 8.2
- Browser: Chrome (also reproducible in Firefox/Safari)
- Timezone: Europe/Berlin (UTC+1)
Steps to Reproduce
- Set your system timezone to something other than UTC (e.g., UTC+1)
- Create a model with a
datetimefield using DatePicker withenableTime: true - Enter a time value (e.g., 14:00)
- Save the record
- Reload the page
- Observe the time has shifted by your timezone offset (shows 15:00 instead of 14:00)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels