devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
327 lines (324 loc) • 11.6 kB
JavaScript
/**
* DevExtreme (cjs/common/core/localization/intl/date.js)
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
;
exports.default = void 0;
var _extend = require("../../../../core/utils/extend");
var _core = _interopRequireDefault(require("../core"));
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
const SYMBOLS_TO_REMOVE_REGEX = /[\u200E\u200F]/g;
const NARROW_NO_BREAK_SPACE_REGEX = /[\u202F]/g;
const getIntlFormatter = format => date => {
if (!format.timeZoneName) {
const year = date.getFullYear();
const recognizableAsTwentyCentury = String(year).length < 3;
const safeYearShift = 400;
const temporaryYearValue = recognizableAsTwentyCentury ? year + safeYearShift : year;
const utcDate = new Date(Date.UTC(temporaryYearValue, date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
if (recognizableAsTwentyCentury) {
utcDate.setFullYear(year)
}
const utcFormat = (0, _extend.extend)({
timeZone: "UTC"
}, format);
return formatDateTime(utcDate, utcFormat)
}
return formatDateTime(date, format)
};
const formattersCache = {};
const getFormatter = format => {
const key = _core.default.locale() + "/" + JSON.stringify(format);
if (!formattersCache[key]) {
formattersCache[key] = new Intl.DateTimeFormat(_core.default.locale(), format).format
}
return formattersCache[key]
};
function formatDateTime(date, format) {
return getFormatter(format)(date).replace(SYMBOLS_TO_REMOVE_REGEX, "").replace(NARROW_NO_BREAK_SPACE_REGEX, " ")
}
const formatNumber = number => new Intl.NumberFormat(_core.default.locale()).format(number);
const getAlternativeNumeralsMap = (() => {
const numeralsMapCache = {};
return locale => {
if (!(locale in numeralsMapCache)) {
if ("0" === formatNumber(0)) {
numeralsMapCache[locale] = false;
return false
}
numeralsMapCache[locale] = {};
for (let i = 0; i < 10; ++i) {
numeralsMapCache[locale][formatNumber(i)] = i
}
}
return numeralsMapCache[locale]
}
})();
const normalizeNumerals = dateString => {
const alternativeNumeralsMap = getAlternativeNumeralsMap(_core.default.locale());
if (!alternativeNumeralsMap) {
return dateString
}
return dateString.split("").map((sign => sign in alternativeNumeralsMap ? String(alternativeNumeralsMap[sign]) : sign)).join("")
};
const removeLeadingZeroes = str => str.replace(/(\D)0+(\d)/g, "$1$2");
const dateStringEquals = (actual, expected) => removeLeadingZeroes(actual) === removeLeadingZeroes(expected);
const normalizeMonth = text => text.replace("d\u2019", "de ");
const intlFormats = {
day: {
day: "numeric"
},
date: {
year: "numeric",
month: "long",
day: "numeric"
},
dayofweek: {
weekday: "long"
},
longdate: {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
},
longdatelongtime: {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric"
},
longtime: {
hour: "numeric",
minute: "numeric",
second: "numeric"
},
month: {
month: "long"
},
monthandday: {
month: "long",
day: "numeric"
},
monthandyear: {
year: "numeric",
month: "long"
},
shortdate: {},
shorttime: {
hour: "numeric",
minute: "numeric"
},
shortyear: {
year: "2-digit"
},
year: {
year: "numeric"
}
};
Object.defineProperty(intlFormats, "shortdateshorttime", {
get: function() {
const defaultOptions = Intl.DateTimeFormat(_core.default.locale()).resolvedOptions();
return {
year: defaultOptions.year,
month: defaultOptions.month,
day: defaultOptions.day,
hour: "numeric",
minute: "numeric"
}
}
});
const getIntlFormat = format => "string" === typeof format && intlFormats[format.toLowerCase()];
const monthNameStrategies = {
standalone: function(monthIndex, monthFormat) {
const date = new Date(1999, monthIndex, 13, 1);
const dateString = getIntlFormatter({
month: monthFormat
})(date);
return dateString
},
format: function(monthIndex, monthFormat) {
const date = new Date(0, monthIndex, 13, 1);
const dateString = normalizeMonth(getIntlFormatter({
day: "numeric",
month: monthFormat
})(date));
const parts = dateString.split(" ").filter((part => part.indexOf("13") < 0));
if (1 === parts.length) {
return parts[0]
} else if (2 === parts.length) {
return parts[0].length > parts[1].length ? parts[0] : parts[1]
}
return monthNameStrategies.standalone(monthIndex, monthFormat)
}
};
var _default = exports.default = {
engine: function() {
return "intl"
},
getMonthNames: function(format, type) {
const monthFormat = {
wide: "long",
abbreviated: "short",
narrow: "narrow"
} [format || "wide"];
type = "format" === type ? type : "standalone";
return Array.apply(null, new Array(12)).map(((_, monthIndex) => monthNameStrategies[type](monthIndex, monthFormat)))
},
getDayNames: function(format) {
const result = (format => Array.apply(null, new Array(7)).map(((_, dayIndex) => getIntlFormatter({
weekday: format
})(new Date(0, 0, dayIndex)))))({
wide: "long",
abbreviated: "short",
short: "narrow",
narrow: "narrow"
} [format || "wide"]);
return result
},
getPeriodNames: function() {
const hour12Formatter = getIntlFormatter({
hour: "numeric",
hour12: true
});
return [1, 13].map((hours => {
const hourNumberText = formatNumber(1);
const timeParts = hour12Formatter(new Date(0, 0, 1, hours)).split(hourNumberText);
if (2 !== timeParts.length) {
return ""
}
const biggerPart = timeParts[0].length > timeParts[1].length ? timeParts[0] : timeParts[1];
return biggerPart.trim()
}))
},
format: function(date, format) {
if (!date) {
return
}
if (!format) {
return date
}
if ("function" !== typeof format && !format.formatter) {
format = format.type || format
}
const intlFormat = getIntlFormat(format);
if (intlFormat) {
return getIntlFormatter(intlFormat)(date)
}
const formatType = typeof format;
if (format.formatter || "function" === formatType || "string" === formatType) {
return this.callBase.apply(this, arguments)
}
return getIntlFormatter(format)(date)
},
parse: function(dateString, format) {
let formatter;
if (format && !format.parser && "string" === typeof dateString) {
dateString = normalizeMonth(dateString);
formatter = date => normalizeMonth(this.format(date, format))
}
return this.callBase(dateString, formatter || format)
},
_parseDateBySimpleFormat: function(dateString, format) {
dateString = normalizeNumerals(dateString);
const formatParts = this.getFormatParts(format);
const dateParts = dateString.split(/\D+/).filter((part => part.length > 0));
if (formatParts.length !== dateParts.length) {
return
}
const dateArgs = this._generateDateArgs(formatParts, dateParts);
const constructValidDate = ampmShift => {
const parsedDate = ((dateArgs, ampmShift) => {
const hoursShift = ampmShift ? 12 : 0;
return new Date(dateArgs.year, dateArgs.month, dateArgs.day, (dateArgs.hours + hoursShift) % 24, dateArgs.minutes, dateArgs.seconds)
})(dateArgs, ampmShift);
if (dateStringEquals(normalizeNumerals(this.format(parsedDate, format)), dateString)) {
return parsedDate
}
};
return constructValidDate(false) || constructValidDate(true)
},
_generateDateArgs: function(formatParts, dateParts) {
const currentDate = new Date;
const dateArgs = {
year: currentDate.getFullYear(),
month: currentDate.getMonth(),
day: currentDate.getDate(),
hours: 0,
minutes: 0,
seconds: 0
};
formatParts.forEach(((formatPart, index) => {
const datePart = dateParts[index];
let parsed = parseInt(datePart, 10);
if ("month" === formatPart) {
parsed -= 1
}
dateArgs[formatPart] = parsed
}));
return dateArgs
},
formatUsesMonthName: function(format) {
if ("object" === typeof format && !(format.type || format.format)) {
return "long" === format.month
}
return this.callBase.apply(this, arguments)
},
formatUsesDayName: function(format) {
if ("object" === typeof format && !(format.type || format.format)) {
return "long" === format.weekday
}
return this.callBase.apply(this, arguments)
},
getTimeSeparator: function() {
return normalizeNumerals(formatDateTime(new Date(2001, 1, 1, 11, 11), {
hour: "numeric",
minute: "numeric",
hour12: false
})).replace(/\d/g, "")
},
getFormatParts: function(format) {
if ("string" === typeof format) {
return this.callBase(format)
}
const intlFormat = (0, _extend.extend)({}, intlFormats[format.toLowerCase()]);
const date = new Date(2001, 2, 4, 5, 6, 7);
let formattedDate = getIntlFormatter(intlFormat)(date);
formattedDate = normalizeNumerals(formattedDate);
return [{
name: "year",
value: 1
}, {
name: "month",
value: 3
}, {
name: "day",
value: 4
}, {
name: "hours",
value: 5
}, {
name: "minutes",
value: 6
}, {
name: "seconds",
value: 7
}].map((part => ({
name: part.name,
index: formattedDate.indexOf(part.value)
}))).filter((part => part.index > -1)).sort(((a, b) => a.index - b.index)).map((part => part.name))
}
};
module.exports = exports.default;
module.exports.default = exports.default;