UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

230 lines (228 loc) • 10.8 kB
/** * DevExtreme (cjs/__internal/scheduler/m_utils_time_zone.js) * Version: 25.2.3 * Build date: Fri Dec 12 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _errors = _interopRequireDefault(require("../../core/errors")); var _date = require("../core/utils/date"); var _index = require("../scheduler/utils/index"); var _date2 = _interopRequireDefault(require("../../core/utils/date")); var _global_cache = require("./global_cache"); var _timezone_list = _interopRequireDefault(require("./timezones/timezone_list")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } const timeZoneListSet = new Set(_timezone_list.default.value); const toMs = _date2.default.dateToMilliseconds; const MINUTES_IN_HOUR = 60; const MS_IN_MINUTE = 6e4; const GMT = "GMT"; const offsetFormatRegexp = /^GMT(?:[+-]\d{2}:\d{2})?$/; const createUTCDateWithLocalOffset = date => { if (!date) { return date } return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())) }; const createDateFromUTCWithLocalOffset = date => new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); const getTimezoneOffsetChangeInMinutes = (startDate, endDate, updatedStartDate, updatedEndDate) => getDaylightOffset(updatedStartDate, updatedEndDate) - getDaylightOffset(startDate, endDate); const getTimezoneOffsetChangeInMs = (startDate, endDate, updatedStartDate, updatedEndDate) => getTimezoneOffsetChangeInMinutes(startDate, endDate, updatedStartDate, updatedEndDate) * toMs("minute"); const getDaylightOffset = (startDate, endDate) => new Date(startDate).getTimezoneOffset() - new Date(endDate).getTimezoneOffset(); const getDaylightOffsetInMs = (startDate, endDate) => getDaylightOffset(startDate, endDate) * toMs("minute"); const calculateTimezoneByValueCore = function(timeZone) { let date = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date; const offset = getStringOffset(timeZone, date); if (void 0 === offset) { return } if (offset === GMT) { return 0 } const isMinus = "-" === offset.substring(3, 4); const hours = offset.substring(4, 6); const minutes = offset.substring(7, 9); const result = parseInt(hours, 10) + parseInt(minutes, 10) / 60; return isMinus ? -result : result }; const calculateTimezoneByValue = function(timeZone) { let date = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date; if (!timeZone) { return } const isValidTimezone = timeZoneListSet.has(timeZone); if (!isValidTimezone) { _errors.default.log("W0009", timeZone); return } const dateObj = new Date(date); if (!_date.dateUtilsTs.isValidDate(dateObj)) { return } if (isEqualLocalTimeZone(timeZone)) { return -dateObj.getTimezoneOffset() / 60 } return calculateTimezoneByValueCore(timeZone, dateObj) }; const getStringOffset = function(timeZone) { let date = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date; let result = ""; try { var _dateTimeFormat$forma; const dateTimeFormat = _global_cache.globalCache.timezones.memo(`intl${timeZone}`, (() => new Intl.DateTimeFormat("en-US", { timeZone: timeZone, timeZoneName: "longOffset" }))); result = (null === (_dateTimeFormat$forma = dateTimeFormat.formatToParts(date).find((_ref => { let { type: type } = _ref; return "timeZoneName" === type }))) || void 0 === _dateTimeFormat$forma ? void 0 : _dateTimeFormat$forma.value) ?? "" } catch (e) { _errors.default.log("W0009", timeZone); return } const isSupportedFormat = offsetFormatRegexp.test(result); if (!isSupportedFormat) { _errors.default.log("W0009", timeZone); return } return result }; const getOffsetNamePart = offset => { if (offset === GMT) { return `${offset} +00:00` } return offset.replace(GMT, `${GMT} `) }; const getTimezoneTitle = function(timeZone) { let date = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date; if (!_date.dateUtilsTs.isValidDate(date)) { return "" } const tzNamePart = timeZone.replace(/\//g, " - ").replace(/_/g, " "); const offset = getStringOffset(timeZone, date); if (void 0 === offset) { return } const offsetNamePart = getOffsetNamePart(offset); return `(${offsetNamePart}) ${tzNamePart}` }; const _getDaylightOffsetByTimezone = (startDate, endDate, timeZone) => { const startDayOffset = calculateTimezoneByValue(timeZone, startDate); const endDayOffset = calculateTimezoneByValue(timeZone, endDate); if (void 0 === startDayOffset || void 0 === endDayOffset) { return 0 } return startDayOffset - endDayOffset }; const getCorrectedDateByDaylightOffsets = (convertedOriginalStartDate, convertedDate, date, timeZone, startDateTimezone) => { const daylightOffsetByCommonTimezone = _getDaylightOffsetByTimezone(convertedOriginalStartDate, convertedDate, timeZone); const daylightOffsetByAppointmentTimezone = _getDaylightOffsetByTimezone(convertedOriginalStartDate, convertedDate, startDateTimezone); const diff = daylightOffsetByCommonTimezone - daylightOffsetByAppointmentTimezone; return new Date(date.getTime() - diff * toMs("hour")) }; const correctRecurrenceExceptionByTimezone = (exception, exceptionByStartDate) => { const timezoneOffset = (exception.getTimezoneOffset() - exceptionByStartDate.getTimezoneOffset()) / 60; return new Date(exception.getTime() + timezoneOffset * toMs("hour")) }; const isTimezoneChangeInDate = date => { const startDayDate = new Date(new Date(date).setHours(0, 0, 0, 0)); const endDayDate = new Date(new Date(date).setHours(23, 59, 59, 0)); return startDayDate.getTimezoneOffset() - endDayDate.getTimezoneOffset() !== 0 }; const getDateWithoutTimezoneChange = date => { const clonedDate = new Date(date); if (isTimezoneChangeInDate(clonedDate)) { const result = new Date(clonedDate); return new Date(result.setDate(result.getDate() + 1)) } return clonedDate }; const isSameAppointmentDates = (startDate, endDate) => { endDate = new Date(endDate.getTime() - 1); return _date2.default.sameDate(startDate, endDate) }; const getClientTimezoneOffset = function() { let date = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : new Date; return 6e4 * date.getTimezoneOffset() }; const getDiffBetweenClientTimezoneOffsets = function() { let firstDate = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : new Date; let secondDate = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date; return getClientTimezoneOffset(firstDate) - getClientTimezoneOffset(secondDate) }; const getMachineTimezoneName = () => _global_cache.globalCache.timezones.memo("localTimezone", (() => _date2.default.getMachineTimezoneName())); const isEqualLocalTimeZone = timeZoneName => { const localTimeZoneName = getMachineTimezoneName(); if (localTimeZoneName && localTimeZoneName === timeZoneName) { return true } return false }; const addOffsetsWithoutDST = function(date) { for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { offsets[_key - 1] = arguments[_key] } const newDate = _date.dateUtilsTs.addOffsets(date, ...offsets); const daylightShift = getDaylightOffsetInMs(date, newDate); if (!daylightShift) { return newDate } const correctLocalDate = _date.dateUtilsTs.addOffsets(newDate, -daylightShift); const daylightSecondShift = getDaylightOffsetInMs(newDate, correctLocalDate); return !daylightSecondShift ? correctLocalDate : newDate }; const getTimeZones = function() { let date = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : new Date; let timeZones = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : _timezone_list.default.value; return timeZones.map((timezoneId => ({ id: timezoneId, title: getTimezoneTitle(timezoneId, date), offset: calculateTimezoneByValue(timezoneId, date) }))) }; const GET_TIMEZONES_BATCH_SIZE = 10; const cacheTimeZones = async () => _global_cache.globalCache.timezones.memo("timeZonesCachePromise", (() => _index.macroTaskArray.map(_timezone_list.default.value, (timezoneId => ({ id: timezoneId, title: getTimezoneTitle(timezoneId, new Date) })), 10).then((data => _global_cache.globalCache.timezones.memo("timeZonesCache", (() => data)))))); const getTimeZonesCache = () => _global_cache.globalCache.timezones.get("timeZonesCache") ?? []; const isLocalTimeMidnightDST = date => { const startDayDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); return 1 === startDayDate.getHours() }; const utils = { getDaylightOffset: getDaylightOffset, getDaylightOffsetInMs: getDaylightOffsetInMs, getTimezoneOffsetChangeInMinutes: getTimezoneOffsetChangeInMinutes, getTimezoneOffsetChangeInMs: getTimezoneOffsetChangeInMs, calculateTimezoneByValue: calculateTimezoneByValue, getCorrectedDateByDaylightOffsets: getCorrectedDateByDaylightOffsets, isSameAppointmentDates: isSameAppointmentDates, correctRecurrenceExceptionByTimezone: correctRecurrenceExceptionByTimezone, getClientTimezoneOffset: getClientTimezoneOffset, getDiffBetweenClientTimezoneOffsets: getDiffBetweenClientTimezoneOffsets, createUTCDateWithLocalOffset: createUTCDateWithLocalOffset, createDateFromUTCWithLocalOffset: createDateFromUTCWithLocalOffset, isTimezoneChangeInDate: isTimezoneChangeInDate, getDateWithoutTimezoneChange: getDateWithoutTimezoneChange, getMachineTimezoneName: getMachineTimezoneName, isEqualLocalTimeZone: isEqualLocalTimeZone, addOffsetsWithoutDST: addOffsetsWithoutDST, getTimeZones: getTimeZones, getTimeZonesCache: getTimeZonesCache, cacheTimeZones: cacheTimeZones, isLocalTimeMidnightDST: isLocalTimeMidnightDST }; var _default = exports.default = utils;