From ad8533186738baca138e7ace73a4a6a816675f6e Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 19 Mar 2019 10:29:19 -0400 Subject: [PATCH] EZEE-2481: Time picker bases on system time ignoring time zone in user settings (#893) * EZEE-2480: Allow user to select date in ezdatetime in their timezone * Use browser timezone from Intl and .tz() from moment js to convert date to date with browser timezone * Fix only convertDateToTimezone from eZ.helpers.timezone * Change how the current set date is evaluated --- .../public/js/scripts/fieldType/ezdatetime.js | 28 ++++++++++++++----- .../js/scripts/helpers/timezone.helper.js | 4 +-- .../Behat/PageElement/DateAndTimePopup.php | 4 +-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/fieldType/ezdatetime.js b/src/bundle/Resources/public/js/scripts/fieldType/ezdatetime.js index 68633b5af7..9c4025bb27 100644 --- a/src/bundle/Resources/public/js/scripts/fieldType/ezdatetime.js +++ b/src/bundle/Resources/public/js/scripts/fieldType/ezdatetime.js @@ -4,6 +4,8 @@ const SELECTOR_FLATPICKR_INPUT = '.flatpickr-input'; const SELECTOR_LABEL_WRAPPER = '.ez-field-edit__label-wrapper'; const EVENT_VALUE_CHANGED = 'valueChanged'; + const { convertDateToTimezone } = eZ.helpers.timezone; + const userTimezone = eZ.adminUiConfig.timezone; class EzDateTimeValidator extends eZ.BaseFieldValidator { /** @@ -63,21 +65,22 @@ const datetimeConfig = { enableTime: true, time_24hr: true, - formatDate: (date) => new Date(date).toLocaleString(), }; - const updateInputValue = (sourceInput, date) => { + const updateInputValue = (sourceInput, dates) => { const event = new CustomEvent(EVENT_VALUE_CHANGED); - if (!date.length) { + if (!dates.length) { sourceInput.value = ''; sourceInput.dispatchEvent(event); return; } - date = new Date(date[0]); - sourceInput.value = Math.floor(date.getTime() / 1000); + const selectedDate = dates[0]; + const selectedDateWithUserTimezone = convertDateToTimezone(selectedDate, userTimezone, true); + const timestamp = Math.floor(selectedDateWithUserTimezone.valueOf() / 1000); + sourceInput.value = timestamp; sourceInput.dispatchEvent(event); }; const clearValue = (sourceInput, flatpickrInstance, event) => { @@ -91,13 +94,24 @@ const sourceInput = field.querySelector(SELECTOR_INPUT); const flatPickrInput = field.querySelector(SELECTOR_FLATPICKR_INPUT); const btnClear = field.querySelector('.ez-data-source__btn--clear-input'); - const defaultDate = sourceInput.value ? new Date(sourceInput.value * 1000) : null; + const secondsEnabled = sourceInput.dataset.seconds === '1'; + const formatDate = secondsEnabled ? (date) => date.toLocaleString() : (date) => eZ.helpers.timezone.formatDate(date); + let defaultDate = null; + + if (sourceInput.value) { + const defaultDateWithUserTimezone = convertDateToTimezone(sourceInput.value * 1000); + const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + defaultDate = new Date(convertDateToTimezone(defaultDateWithUserTimezone, browserTimezone, true)); + } + const flatpickrInstance = flatpickr( flatPickrInput, Object.assign({}, datetimeConfig, { onChange: updateInputValue.bind(null, sourceInput), defaultDate, - enableSeconds: !!parseInt(sourceInput.dataset.seconds, 10), + enableSeconds: secondsEnabled, + formatDate, }) ); diff --git a/src/bundle/Resources/public/js/scripts/helpers/timezone.helper.js b/src/bundle/Resources/public/js/scripts/helpers/timezone.helper.js index 6714620bd0..07c9c790d1 100644 --- a/src/bundle/Resources/public/js/scripts/helpers/timezone.helper.js +++ b/src/bundle/Resources/public/js/scripts/helpers/timezone.helper.js @@ -3,8 +3,8 @@ const userPreferedFullDateFormat = eZ.adminUiConfig.dateFormat.full; const userPreferedShortDateFormat = eZ.adminUiConfig.dateFormat.short; - const convertDateToTimezone = (date, timezone = userPreferedTimezone) => { - return moment(date).tz(timezone); + const convertDateToTimezone = (date, timezone = userPreferedTimezone, forceSameTime = false) => { + return moment(date).tz(timezone, forceSameTime); }; const formatDate = (date, format = userPreferedFullDateFormat) => { return moment(date).formatPHP(format); diff --git a/src/lib/Behat/PageElement/DateAndTimePopup.php b/src/lib/Behat/PageElement/DateAndTimePopup.php index a4e74fa78c..cbf8588b6f 100644 --- a/src/lib/Behat/PageElement/DateAndTimePopup.php +++ b/src/lib/Behat/PageElement/DateAndTimePopup.php @@ -47,9 +47,7 @@ public function setTime(string $hour, string $minute): void if (!$isTimeOnly) { // get current date as it's not possible to set time without setting date - $currentDateScript = sprintf('document.querySelector("%s %s")._flatpickr.formatDate(document.querySelector("%s %s")._flatpickr.selectedDates, "Y-m-d")', - $this->fields['containerSelector'], - $this->fields['flatpickrSelector'], + $currentDateScript = sprintf('document.querySelector("%s %s")._flatpickr.selectedDates[0].toLocaleString()', $this->fields['containerSelector'], $this->fields['flatpickrSelector']); $currentDate = $this->context->getSession()->getDriver()->evaluateScript($currentDateScript);