UNPKG

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
/** * 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