devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
128 lines (127 loc) • 5.1 kB
JavaScript
/**
* DevExtreme (esm/__internal/core/localization/ldml/date.formatter.js)
* Version: 25.2.7
* Build date: Tue May 05 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
function leftPad(text, length) {
while (text.length < length) {
text = `0${text}`
}
return text
}
const FORMAT_TYPES = {
3: "abbreviated",
4: "wide",
5: "narrow"
};
const LDML_FORMATTERS = {
y(date, count, useUtc) {
let year = date[useUtc ? "getUTCFullYear" : "getFullYear"]();
if (2 === count) {
year %= 100
}
return leftPad(year.toString(), count)
},
M(date, count, useUtc, dateParts) {
const month = date[useUtc ? "getUTCMonth" : "getMonth"]();
const formatType = FORMAT_TYPES[count];
if (formatType) {
return dateParts.getMonthNames(formatType, "format")[month]
}
return leftPad((month + 1).toString(), Math.min(count, 2))
},
L(date, count, useUtc, dateParts) {
const month = date[useUtc ? "getUTCMonth" : "getMonth"]();
const formatType = FORMAT_TYPES[count];
if (formatType) {
return dateParts.getMonthNames(formatType, "standalone")[month]
}
return leftPad((month + 1).toString(), Math.min(count, 2))
},
Q(date, count, useUtc, dateParts) {
const month = date[useUtc ? "getUTCMonth" : "getMonth"]();
const quarter = Math.floor(month / 3);
const formatType = FORMAT_TYPES[count];
if (formatType) {
return dateParts.getQuarterNames(formatType)[quarter]
}
return leftPad((quarter + 1).toString(), Math.min(count, 2))
},
E(date, count, useUtc, dateParts) {
const day = date[useUtc ? "getUTCDay" : "getDay"]();
const formatType = FORMAT_TYPES[count < 3 ? 3 : count];
return dateParts.getDayNames(formatType)[day]
},
a(date, count, useUtc, dateParts) {
const hours = date[useUtc ? "getUTCHours" : "getHours"]();
const period = hours < 12 ? 0 : 1;
const formatType = FORMAT_TYPES[count];
return dateParts.getPeriodNames(formatType)[period]
},
d: (date, count, useUtc) => leftPad(date[useUtc ? "getUTCDate" : "getDate"]().toString(), Math.min(count, 2)),
H: (date, count, useUtc) => leftPad(date[useUtc ? "getUTCHours" : "getHours"]().toString(), Math.min(count, 2)),
h(date, count, useUtc) {
const hours = date[useUtc ? "getUTCHours" : "getHours"]();
return leftPad((hours % 12 || 12).toString(), Math.min(count, 2))
},
m: (date, count, useUtc) => leftPad(date[useUtc ? "getUTCMinutes" : "getMinutes"]().toString(), Math.min(count, 2)),
s: (date, count, useUtc) => leftPad(date[useUtc ? "getUTCSeconds" : "getSeconds"]().toString(), Math.min(count, 2)),
S: (date, count, useUtc) => leftPad(date[useUtc ? "getUTCMilliseconds" : "getMilliseconds"]().toString(), 3).substr(0, count),
x(date, count, useUtc) {
const timezoneOffset = useUtc ? 0 : date.getTimezoneOffset();
const signPart = timezoneOffset > 0 ? "-" : "+";
const timezoneOffsetAbs = Math.abs(timezoneOffset);
const hours = Math.floor(timezoneOffsetAbs / 60);
const minutes = timezoneOffsetAbs % 60;
const hoursPart = leftPad(hours.toString(), 2);
const minutesPart = leftPad(minutes.toString(), 2);
return signPart + hoursPart + (count >= 3 ? ":" : "") + (count > 1 || minutes ? minutesPart : "")
},
X(date, count, useUtc) {
if (useUtc || !date.getTimezoneOffset()) {
return "Z"
}
return LDML_FORMATTERS.x(date, count, useUtc)
},
Z: (date, count, useUtc) => LDML_FORMATTERS.X(date, count >= 5 ? 3 : 2, useUtc)
};
export const getFormatter = (format, dateParts) => date => {
let charIndex;
let formatter;
let char;
let charCount = 0;
let isEscaping = false;
let isCurrentCharEqualsNext;
let result = "";
if (!date) {
return null
}
if (!format) {
return date
}
const useUtc = format.endsWith("Z") || format.endsWith("'Z'");
for (charIndex = 0; charIndex < format.length; charIndex += 1) {
char = format[charIndex];
formatter = LDML_FORMATTERS[char];
isCurrentCharEqualsNext = char === format[charIndex + 1];
charCount += 1;
if (!isCurrentCharEqualsNext) {
if (formatter && !isEscaping) {
result += formatter(date, charCount, useUtc, dateParts)
}
charCount = 0
}
if ("'" === char && !isCurrentCharEqualsNext) {
isEscaping = !isEscaping
} else if (isEscaping || !formatter) {
result += char
}
if ("'" === char && isCurrentCharEqualsNext) {
charIndex += 1
}
}
return result
};