UNPKG

@telerik/kendo-intl

Version:

A package exporting functions for date and number parsing and formatting

241 lines (207 loc) 6.84 kB
import formatString from '../common/format-string'; import isString from '../common/is-string'; import { EMPTY } from '../common/constants'; var REMOVAL_PENALTY = 120; var ADDITION_PENALTY = 20; var LENGHT_DELTA = [ 2, 1, 5, 3, 4 ]; var LONG_LESS_PENALTY_DELTA = -2; var SHORT_LESS_PENALTY_DELTA = -1; var SHORT_MORE_PENALTY_DELTA = 1; var LONG_MORE_PENALTY_DELTA = 2; var PENALTIES = {}; PENALTIES[LONG_LESS_PENALTY_DELTA.toString()] = 8; PENALTIES[SHORT_LESS_PENALTY_DELTA.toString()] = 6; PENALTIES[LONG_MORE_PENALTY_DELTA.toString()] = 6; PENALTIES[SHORT_MORE_PENALTY_DELTA.toString()] = 3; var VALUE_FORMAT_LENGTH = { numeric: 1, "2-digit": 2, short: 3, long: 4, narrow: 5 }; var TIME_SPECIFIERS_REGEX = /[hHmsSzZoOvVxX]/; function getHourSpecifier(options) { return options.hour12 ? "h" : "H"; } var DATE_OPTIONS_MAP = [ { key: "era", specifier: "G" }, { key: "year", specifier: "y" }, { key: "month", specifier: "M" }, { key: "day", specifier: "d" }, { key: "weekday", specifier: "E" }, { key: "hour", getSpecifier: getHourSpecifier }, { key: "minute", specifier: "m" }, { key: "second", specifier: "s" }, { key: "timeZoneName", specifier: "z" } ]; var STAND_ALONE_SPECIFIERS = { e: 'c', E: 'c', M: 'L', Q: 'q' }; var specifiersRegex = {}; var resolvedFormats = {}; function getSpecifierRegex(specifier) { if (!specifiersRegex[specifier]) { specifiersRegex[specifier] = new RegExp(specifier + "+"); } return specifiersRegex[specifier]; } function skeletonSpecifiers(skeleton) { var result = []; var current = skeleton.charAt(0); var specifier = current; for (var idx = 1; idx < skeleton.length; idx++) { var character = skeleton.charAt(idx); if (character === specifier) { current += character; } else { result.push(current); current = specifier = character; } } result.push(current); return result; } function findBestMatch(specifiers, availableFormats) { var specifiersLength = specifiers.length; var maxScore = -Number.MAX_VALUE; var bestMatches, result; for (var format in availableFormats) { var matches = []; var currentFormat = format.replace("v", "z"); var score = 0; for (var idx = 0; idx < specifiersLength; idx++) { var specifier = specifiers[idx]; var specifierRegex = getSpecifierRegex(specifier[0]); var match = (specifierRegex.exec(currentFormat) || [])[0]; if (!match) { score -= REMOVAL_PENALTY; } else { currentFormat = currentFormat.replace(match, EMPTY); if (match.length !== specifier.length) { var delta = Math.max(Math.min(LENGHT_DELTA[match.length] - LENGHT_DELTA[specifier.length], 2), -2); score -= PENALTIES[delta]; } } matches.push(match); if (score < maxScore) { break; } } if (currentFormat.length) { score -= skeletonSpecifiers(currentFormat).length * ADDITION_PENALTY; } if (score > maxScore) { maxScore = score; bestMatches = matches; result = availableFormats[format]; } } result = result.replace("v", "z"); for (var idx$1 = 0; idx$1 < specifiersLength; idx$1++) { var bestMatch = bestMatches[idx$1]; if (bestMatch && bestMatch !== specifiers[idx$1]) { var matchSpecifier = bestMatches[idx$1][0]; result = result.replace(getSpecifierRegex(matchSpecifier), specifiers[idx$1]); if (STAND_ALONE_SPECIFIERS[matchSpecifier]) { result = result.replace(getSpecifierRegex(STAND_ALONE_SPECIFIERS[matchSpecifier]), specifiers[idx$1]); } } } return result; } function cacheFormat(skeleton, format, locale) { if (!resolvedFormats[locale]) { resolvedFormats[locale] = {}; } resolvedFormats[locale][skeleton] = format; } function skeletonFormat(skeleton, info) { var availableFormats = info.calendar.dateTimeFormats.availableFormats; if (availableFormats[skeleton]) { return availableFormats[skeleton]; } if (resolvedFormats[info.name] && resolvedFormats[info.name][skeleton]) { return resolvedFormats[info.name][skeleton]; } var timeStartIndex = skeleton.search(TIME_SPECIFIERS_REGEX); var result; if (timeStartIndex > 0) { var dateSkeleton = skeleton.substr(0, timeStartIndex); var timeSkeleton = skeleton.substr(timeStartIndex); result = formatString(info.calendar.dateTimeFormats.short, //should be deterimed based on specifiers availableFormats[timeSkeleton] || findBestMatch(skeletonSpecifiers(timeSkeleton), availableFormats), availableFormats[dateSkeleton] || findBestMatch(skeletonSpecifiers(dateSkeleton), availableFormats)); } else { result = findBestMatch(skeletonSpecifiers(skeleton), availableFormats); } cacheFormat(skeleton, result, info.name); return result; } function skeletonFromOptions(options) { var result = []; for (var idx = 0; idx < DATE_OPTIONS_MAP.length; idx++) { var option = DATE_OPTIONS_MAP[idx]; var field = option.key; var value = options[field]; if (value) { var spcifier = option.specifier || option.getSpecifier(options); result.push(spcifier.repeat(VALUE_FORMAT_LENGTH[value])); } } return result.join(EMPTY); } export default function datePattern(format, info) { var calendar = info.calendar; var result; if (isString(format)) { if (calendar.patterns[format]) { result = calendar.patterns[format]; } else { result = format; } } else if (format) { if (format.pattern) { return format.pattern; } var skeleton = format.skeleton; if (!skeleton) { if (format.datetime) { result = formatString(calendar.dateTimeFormats[format.datetime], calendar.timeFormats[format.datetime], calendar.dateFormats[format.datetime]); } else if (format.date) { result = calendar.dateFormats[format.date]; } else if (format.time) { result = calendar.timeFormats[format.time]; } else { skeleton = skeletonFromOptions(format); } } if (skeleton) { result = skeletonFormat(skeleton, info); } } if (!result) { result = calendar.patterns.d; } return result; }