timezonecomplete
Version:
DateTime, TimeZone, Duration and Period library aimed at providing a consistent and complete date-time interface, away from the original JavaScript Date class.
606 lines • 21.4 kB
JavaScript
/**
* Copyright(c) 2014 ABB Switzerland Ltd.
*
* Functionality to parse a DateTime object to a string
*/
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.format = void 0;
var basics = require("./basics");
var error_1 = require("./error");
var locale_1 = require("./locale");
var strings = require("./strings");
var token_1 = require("./token");
/**
* Format the supplied dateTime with the formatting string.
*
* @param dateTime The current time to format
* @param utcTime The time in UTC
* @param localZone The zone that currentTime is in
* @param formatString The LDML format pattern (see LDML.md)
* @param locale Other format options such as month names
* @return string
* @throws timezonecomplete.Argument.FormatString for invalid format pattern
* @throws timezonecomplete.InvalidTimeZoneData if values in the time zone database are invalid
*/
function format(dateTime, utcTime, localZone, formatString, locale) {
if (locale === void 0) { locale = {}; }
var mergedLocale = __assign(__assign({}, locale_1.DEFAULT_LOCALE), locale);
var tokens = (0, token_1.tokenize)(formatString);
var result = "";
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
var token = tokens_1[_i];
var tokenResult = void 0;
switch (token.type) {
case token_1.TokenType.ERA:
tokenResult = _formatEra(dateTime, token, mergedLocale);
break;
case token_1.TokenType.YEAR:
tokenResult = _formatYear(dateTime, token);
break;
case token_1.TokenType.QUARTER:
tokenResult = _formatQuarter(dateTime, token, mergedLocale);
break;
case token_1.TokenType.MONTH:
tokenResult = _formatMonth(dateTime, token, mergedLocale);
break;
case token_1.TokenType.DAY:
tokenResult = _formatDay(dateTime, token);
break;
case token_1.TokenType.WEEKDAY:
tokenResult = _formatWeekday(dateTime, token, mergedLocale);
break;
case token_1.TokenType.DAYPERIOD:
tokenResult = _formatDayPeriod(dateTime, token, mergedLocale);
break;
case token_1.TokenType.HOUR:
tokenResult = _formatHour(dateTime, token);
break;
case token_1.TokenType.MINUTE:
tokenResult = _formatMinute(dateTime, token);
break;
case token_1.TokenType.SECOND:
tokenResult = _formatSecond(dateTime, token);
break;
case token_1.TokenType.ZONE:
tokenResult = _formatZone(dateTime, utcTime, localZone ? localZone : undefined, token);
break;
case token_1.TokenType.WEEK:
tokenResult = _formatWeek(dateTime, token);
break;
case token_1.TokenType.IDENTITY: // intentional fallthrough
/* istanbul ignore next */
default:
tokenResult = token.raw;
break;
}
result += tokenResult;
}
return result.trim();
}
exports.format = format;
/**
* Format the era (BC or AD)
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatEra(dateTime, token, locale) {
var AD = dateTime.year > 0;
switch (token.length) {
case 1:
case 2:
case 3:
return (AD ? locale.eraAbbreviated[0] : locale.eraAbbreviated[1]);
case 4:
return (AD ? locale.eraWide[0] : locale.eraWide[1]);
case 5:
return (AD ? locale.eraNarrow[0] : locale.eraNarrow[1]);
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the year
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatYear(dateTime, token) {
switch (token.symbol) {
case "y":
case "Y":
case "r":
var yearValue = strings.padLeft(dateTime.year.toString(), token.length, "0");
if (token.length === 2) { // Special case: exactly two characters are expected
yearValue = yearValue.slice(-2);
}
return yearValue;
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the quarter
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws timezonecomplete.Argument.FormatString for invalid format pattern
*/
function _formatQuarter(dateTime, token, locale) {
var quarter = Math.ceil(dateTime.month / 3);
switch (token.symbol) {
case "Q":
switch (token.length) {
case 1:
case 2:
return strings.padLeft(quarter.toString(), 2, "0");
case 3:
return locale.quarterLetter + quarter;
case 4:
return locale.quarterAbbreviations[quarter - 1] + " " + locale.quarterWord;
case 5:
return quarter.toString();
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
case "q":
switch (token.length) {
case 1:
case 2:
return strings.padLeft(quarter.toString(), 2, "0");
case 3:
return locale.standAloneQuarterLetter + quarter;
case 4:
return locale.standAloneQuarterAbbreviations[quarter - 1] + " " + locale.standAloneQuarterWord;
case 5:
return quarter.toString();
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
/* istanbul ignore next */
default:
/* istanbul ignore next */
return (0, error_1.throwError)("Argument.FormatString", "invalid quarter pattern");
}
}
/**
* Format the month
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws timezonecomplete.Argument.FormatString for invalid format pattern
*/
function _formatMonth(dateTime, token, locale) {
switch (token.symbol) {
case "M":
switch (token.length) {
case 1:
case 2:
return strings.padLeft(dateTime.month.toString(), token.length, "0");
case 3:
return locale.shortMonthNames[dateTime.month - 1];
case 4:
return locale.longMonthNames[dateTime.month - 1];
case 5:
return locale.monthLetters[dateTime.month - 1];
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
case "L":
switch (token.length) {
case 1:
case 2:
return strings.padLeft(dateTime.month.toString(), token.length, "0");
case 3:
return locale.standAloneShortMonthNames[dateTime.month - 1];
case 4:
return locale.standAloneLongMonthNames[dateTime.month - 1];
case 5:
return locale.standAloneMonthLetters[dateTime.month - 1];
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
/* istanbul ignore next */
default:
/* istanbul ignore next */
return (0, error_1.throwError)("Argument.FormatString", "invalid month pattern");
}
}
/**
* Format the week number
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatWeek(dateTime, token) {
if (token.symbol === "w") {
return strings.padLeft(basics.weekNumber(dateTime.year, dateTime.month, dateTime.day).toString(), token.length, "0");
}
else {
return strings.padLeft(basics.weekOfMonth(dateTime.year, dateTime.month, dateTime.day).toString(), token.length, "0");
}
}
/**
* Format the day of the month (or year)
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatDay(dateTime, token) {
switch (token.symbol) {
case "d":
return strings.padLeft(dateTime.day.toString(), token.length, "0");
case "D":
var dayOfYear = basics.dayOfYear(dateTime.year, dateTime.month, dateTime.day) + 1;
return strings.padLeft(dayOfYear.toString(), token.length, "0");
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the day of the week
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatWeekday(dateTime, token, locale) {
var weekDayNumber = basics.weekDayNoLeapSecs(dateTime.unixMillis);
switch (token.length) {
case 1:
case 2:
if (token.symbol === "e") {
return strings.padLeft(basics.weekDayNoLeapSecs(dateTime.unixMillis).toString(), token.length, "0");
}
else {
return locale.shortWeekdayNames[weekDayNumber];
}
case 3:
return locale.shortWeekdayNames[weekDayNumber];
case 4:
return locale.longWeekdayNames[weekDayNumber];
case 5:
return locale.weekdayLetters[weekDayNumber];
case 6:
return locale.weekdayTwoLetters[weekDayNumber];
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the Day Period (AM or PM)
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatDayPeriod(dateTime, token, locale) {
switch (token.symbol) {
case "a": {
if (token.length <= 3) {
if (dateTime.hour < 12) {
return locale.dayPeriodAbbreviated.am;
}
else {
return locale.dayPeriodAbbreviated.pm;
}
}
else if (token.length === 4) {
if (dateTime.hour < 12) {
return locale.dayPeriodWide.am;
}
else {
return locale.dayPeriodWide.pm;
}
}
else {
if (dateTime.hour < 12) {
return locale.dayPeriodNarrow.am;
}
else {
return locale.dayPeriodNarrow.pm;
}
}
}
case "b":
case "B": {
if (token.length <= 3) {
if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodAbbreviated.midnight;
}
else if (dateTime.hour === 12 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodAbbreviated.noon;
}
else if (dateTime.hour < 12) {
return locale.dayPeriodAbbreviated.am;
}
else {
return locale.dayPeriodAbbreviated.pm;
}
}
else if (token.length === 4) {
if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodWide.midnight;
}
else if (dateTime.hour === 12 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodWide.noon;
}
else if (dateTime.hour < 12) {
return locale.dayPeriodWide.am;
}
else {
return locale.dayPeriodWide.pm;
}
}
else {
if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodNarrow.midnight;
}
else if (dateTime.hour === 12 && dateTime.minute === 0 && dateTime.second === 0 && dateTime.milli === 0) {
return locale.dayPeriodNarrow.noon;
}
else if (dateTime.hour < 12) {
return locale.dayPeriodNarrow.am;
}
else {
return locale.dayPeriodNarrow.pm;
}
}
}
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the Hour
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatHour(dateTime, token) {
var hour = dateTime.hour;
switch (token.symbol) {
case "h":
hour = hour % 12;
if (hour === 0) {
hour = 12;
}
return strings.padLeft(hour.toString(), token.length, "0");
case "H":
return strings.padLeft(hour.toString(), token.length, "0");
case "K":
hour = hour % 12;
return strings.padLeft(hour.toString(), token.length, "0");
case "k":
if (hour === 0) {
hour = 24;
}
return strings.padLeft(hour.toString(), token.length, "0");
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the minute
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws nothing
*/
function _formatMinute(dateTime, token) {
return strings.padLeft(dateTime.minute.toString(), token.length, "0");
}
/**
* Format the seconds (or fraction of a second)
*
* @param dateTime The current time to format
* @param token The token passed
* @return string
* @throws timezonecomplete.Argument.** if any of the given dateTime elements are invalid
*/
function _formatSecond(dateTime, token) {
switch (token.symbol) {
case "s":
return strings.padLeft(dateTime.second.toString(), token.length, "0");
case "S":
var fraction = dateTime.milli;
var fractionString = strings.padLeft(fraction.toString(), 3, "0");
fractionString = strings.padRight(fractionString, token.length, "0");
return fractionString.slice(0, token.length);
case "A":
return strings.padLeft(basics.secondOfDay(dateTime.hour, dateTime.minute, dateTime.second).toString(), token.length, "0");
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
/**
* Format the time zone. For this, we need the current time, the time in UTC and the time zone
* @param currentTime The time to format
* @param utcTime The time in UTC
* @param zone The timezone currentTime is in
* @param token The token passed
* @return string
* @throws timezonecomplete.InvalidTimeZoneData if values in the time zone database are invalid
*/
function _formatZone(currentTime, utcTime, zone, token) {
if (!zone) {
return "";
}
var offset = Math.round((currentTime.unixMillis - utcTime.unixMillis) / 60000);
var offsetHours = Math.floor(Math.abs(offset) / 60);
var offsetHoursString = strings.padLeft(offsetHours.toString(), 2, "0");
offsetHoursString = (offset >= 0 ? "+" + offsetHoursString : "-" + offsetHoursString);
var offsetMinutes = Math.abs(offset % 60);
var offsetMinutesString = strings.padLeft(offsetMinutes.toString(), 2, "0");
var result;
switch (token.symbol) {
case "O":
result = "GMT";
if (offset >= 0) {
result += "+";
}
else {
result += "-";
}
result += offsetHours.toString();
if (token.length >= 4 || offsetMinutes !== 0) {
result += ":" + offsetMinutesString;
}
if (token.length > 4) {
result += token.raw.slice(4);
}
return result;
case "Z":
switch (token.length) {
case 1:
case 2:
case 3:
return offsetHoursString + offsetMinutesString;
case 4:
var newToken = {
length: 4,
raw: "OOOO",
symbol: "O",
type: token_1.TokenType.ZONE
};
return _formatZone(currentTime, utcTime, zone, newToken);
case 5:
if (offset === 0) {
return "Z";
}
return offsetHoursString + ":" + offsetMinutesString;
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
case "z":
switch (token.length) {
case 1:
case 2:
case 3:
return zone.abbreviationForUtc(currentTime, true);
case 4:
return zone.toString();
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
case "v":
if (token.length === 1) {
return zone.abbreviationForUtc(currentTime, false);
}
else {
return zone.toString();
}
case "V":
switch (token.length) {
case 1:
// Not implemented
return "unk";
case 2:
return zone.name();
case 3:
case 4:
return "Unknown";
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
case "X":
case "x":
if (token.symbol === "X" && offset === 0) {
return "Z";
}
switch (token.length) {
case 1:
result = offsetHoursString;
if (offsetMinutes !== 0) {
result += offsetMinutesString;
}
return result;
case 2:
case 4: // No seconds in our implementation, so this is the same
return offsetHoursString + offsetMinutesString;
case 3:
case 5: // No seconds in our implementation, so this is the same
return offsetHoursString + ":" + offsetMinutesString;
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
/* istanbul ignore next */
default:
// tokenizer should prevent this
/* istanbul ignore next */
return token.raw;
}
}
//# sourceMappingURL=format.js.map