@phensley/cldr-core
Version:
Core library for @phensley/cldr
460 lines • 18.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var min = Math.min;
var getTZC = function (offset) {
var negative = offset < 0;
if (negative) {
offset *= -1;
}
offset /= 60000;
var hours = offset / 60 | 0;
var minutes = offset % 60;
return [offset, negative, hours, minutes];
};
var widthKey1 = function (w) { return w === 5 ? 'narrow' : w === 4 ? 'wide' : 'abbreviated'; };
var CalendarFormatter = /** @class */ (function () {
function CalendarFormatter(internals, cal) {
this.internals = internals;
this.cal = cal;
this.wrapper = internals.wrapper;
this.tz = internals.schema.TimeZones;
}
CalendarFormatter.prototype.format = function (rnd, ctx, nodes) {
for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
var n = nodes_1[_i];
if (typeof n === 'string') {
rnd.add('literal', n);
continue;
}
switch (n[0]) {
case 'G':
rnd.add('era', this.era(ctx, n[1]));
break;
case 'y':
rnd.add('year', this.year(ctx, n[1]));
break;
case 'Y':
rnd.add('year', this.yearOfWeekYear(ctx, n[1]));
break;
case 'u':
rnd.add('year', this.extendedYear(ctx, n[1]));
break;
case 'U':
rnd.add('cyclic-year', this.cyclicYear(ctx, n[1]));
break;
case 'r':
rnd.add('related-year', this.relatedYear(ctx, n[1]));
break;
case 'Q':
case 'q':
rnd.add('quarter', this.quarter(ctx, n));
break;
case 'M':
case 'L':
rnd.add('month', this.month(ctx, n));
break;
// 'l' - deprecated
case 'w':
rnd.add('week', this.weekOfWeekYear(ctx, n));
break;
case 'W':
rnd.add('week', this.weekOfMonth(ctx, n));
break;
case 'd':
rnd.add('day', this.dayOfMonth(ctx, n));
break;
case 'D':
rnd.add('day', this.dayOfYear(ctx, n));
break;
case 'F':
rnd.add('day', this.dayOfWeekInMonth(ctx, n));
break;
case 'g':
rnd.add('mjulian-day', this.modifiedJulianDay(ctx, n));
break;
case 'E':
rnd.add('weekday', this.weekday(ctx, n));
break;
case 'e':
rnd.add('weekday', this.weekdayLocal(ctx, n));
break;
case 'c':
rnd.add('weekday', this.weekdayLocalStandalone(ctx, n));
break;
case 'a':
rnd.add('dayperiod', this.dayPeriod(ctx, n));
break;
case 'b':
rnd.add('dayperiod', this.dayPeriodExt(ctx, n));
break;
case 'B':
rnd.add('dayperiod', this.dayPeriodFlex(ctx, n));
break;
case 'h':
case 'H':
rnd.add('hour', this.hour(ctx, n));
break;
case 'K':
case 'k':
rnd.add('hour', this.hourAlt(ctx, n));
break;
// 'j', 'J', 'C' - input skeleton symbols, not present in formats
case 'm':
rnd.add('minute', this.minute(ctx, n));
break;
case 's':
rnd.add('second', this.second(ctx, n));
break;
case 'S':
rnd.add('fracsec', this.fractionalSecond(ctx, n));
break;
case 'A':
rnd.add('millis-in-day', this.millisInDay(ctx, n));
break;
case 'z':
rnd.add('timezone', this.timezone_z(ctx, n));
break;
case 'Z':
rnd.add('timezone', this.timezone_Z(ctx, n));
break;
case 'O':
rnd.add('timezone', this.timezone_O(ctx, n));
break;
case 'v':
rnd.add('timezone', this.timezone_v(ctx, n));
break;
case 'V':
rnd.add('timezone', this.timezone_V(ctx, n));
break;
case 'X':
case 'x':
rnd.add('timezone', this.timezone_x(ctx, n));
break;
}
}
};
/**
* Format a number using the main numbering system, with the given minimum integers.
*/
CalendarFormatter.prototype._num = function (ctx, n, minInt) {
return ctx.system.formatString(n, false, minInt);
};
CalendarFormatter.prototype.era = function (ctx, width) {
var key1 = width === 5 ? 'narrow' : width === 4 ? 'names' : 'abbr';
return this.cal.eras.get(ctx.bundle, key1, "" + ctx.date.era());
};
CalendarFormatter.prototype.year = function (ctx, width) {
return this._year(ctx, ctx.date.year(), width);
};
CalendarFormatter.prototype.yearOfWeekYear = function (ctx, width) {
return this._year(ctx, ctx.date.yearOfWeekOfYear(), width);
};
CalendarFormatter.prototype.extendedYear = function (ctx, width) {
return this._num(ctx, ctx.date.extendedYear(), width);
};
/**
* Cyclic year.
*/
CalendarFormatter.prototype.cyclicYear = function (ctx, width) {
// TODO: Supported in Chinese calendar.
return '';
};
/**
* Related Gregorian year.
*/
CalendarFormatter.prototype.relatedYear = function (ctx, width) {
// Note: this is always rendered using 'latn' digits
return ctx.latnSystem.formatString(ctx.date.relatedYear(), false, width);
};
CalendarFormatter.prototype._year = function (ctx, year, width) {
return this._num(ctx, width === 2 ? year % 100 : year, width);
};
CalendarFormatter.prototype._formatQuarterOrMonth = function (ctx, format, value, width) {
return width >= 3 ? format.get(ctx.bundle, widthKey1(width), String(value)) : this._num(ctx, value, width);
};
CalendarFormatter.prototype.quarter = function (ctx, node) {
var field = node[0], width = node[1];
var format = field === 'Q' ? this.cal.format : this.cal.standAlone;
var quarters = format.quarters;
var quarter = ((ctx.date.month() - 1) / 3 | 0) + 1;
return this._formatQuarterOrMonth(ctx, quarters, quarter, width);
};
CalendarFormatter.prototype.month = function (ctx, node) {
var format = node[0] === 'M' ? this.cal.format : this.cal.standAlone;
return this._formatQuarterOrMonth(ctx, format.months, ctx.date.month(), node[1]);
};
CalendarFormatter.prototype.weekOfWeekYear = function (ctx, node) {
return this._num(ctx, ctx.date.weekOfYear(), min(node[1], 2));
};
CalendarFormatter.prototype.weekOfMonth = function (ctx, node) {
return this._num(ctx, ctx.date.weekOfMonth(), 1);
};
CalendarFormatter.prototype.dayOfMonth = function (ctx, node) {
return this._num(ctx, ctx.date.dayOfMonth(), min(node[1], 2));
};
CalendarFormatter.prototype.dayOfYear = function (ctx, node) {
return this._num(ctx, ctx.date.dayOfYear(), min(node[1], 3));
};
CalendarFormatter.prototype.dayOfWeekInMonth = function (ctx, node) {
return this._num(ctx, ctx.date.dayOfWeekInMonth(), 1);
};
CalendarFormatter.prototype.modifiedJulianDay = function (ctx, node) {
return this._num(ctx, ctx.date.modifiedJulianDay(), node[1]);
};
CalendarFormatter.prototype.weekday = function (ctx, node) {
return this._weekday(ctx.bundle, this.cal.format.weekdays, ctx.date, node[1]);
};
CalendarFormatter.prototype.weekdayLocal = function (ctx, node) {
return this._weekdayLocal(ctx, node, false);
};
CalendarFormatter.prototype.weekdayLocalStandalone = function (ctx, node) {
return this._weekdayLocal(ctx, node, true);
};
CalendarFormatter.prototype._weekday = function (bundle, format, date, width) {
var key2 = String(date.dayOfWeek());
var key1 = 'abbreviated';
switch (width) {
case 6:
key1 = 'short';
break;
case 5:
key1 = 'narrow';
break;
case 4:
key1 = 'wide';
break;
}
return format.get(bundle, key1, key2);
};
CalendarFormatter.prototype._weekdayLocal = function (ctx, node, standAlone) {
var bundle = ctx.bundle, date = ctx.date;
var width = node[1];
if (width > 2) {
var format = standAlone ? this.cal.standAlone : this.cal.format;
return this._weekday(bundle, format.weekdays, date, width);
}
var ord = date.ordinalDayOfWeek();
if (standAlone) {
width = 1;
}
return ctx.system.formatString(ord, false, width);
};
CalendarFormatter.prototype.dayPeriod = function (ctx, node) {
return this.cal.format.dayPeriods.get(ctx.bundle, widthKey1(node[1]), ctx.date.hourOfDay() < 12 ? 'am' : 'pm');
};
CalendarFormatter.prototype.dayPeriodExt = function (ctx, node) {
var bundle = ctx.bundle, date = ctx.date;
var key1 = widthKey1(node[1]);
var key2 = date.isAM() ? 'am' : 'pm';
var key2ext = key2;
if (date.minute() === 0) {
var hour = date.hourOfDay();
key2ext = hour === 0 ? 'midnight' : hour === 12 ? 'noon' : key2;
}
var format = this.cal.format.dayPeriods;
// Try extended and if it doesn't exist fall back to am/pm
return format.get(bundle, key1, key2ext) || format.get(bundle, key1, key2);
};
CalendarFormatter.prototype.dayPeriodFlex = function (ctx, node) {
var bundle = ctx.bundle, date = ctx.date;
var minutes = (date.hourOfDay() * 60) + date.minute();
var key2 = this.internals.calendars.flexDayPeriod(bundle, minutes);
var res = '';
if (key2) {
res = this.cal.format.dayPeriods.get(bundle, widthKey1(node[1]), key2);
}
return res ? res : this.dayPeriodExt(ctx, node);
};
CalendarFormatter.prototype.hour = function (ctx, node) {
var date = ctx.date;
var twelve = node[0] === 'h';
var hour = twelve ? date.hour() : date.hourOfDay();
if (twelve && hour === 0) {
hour = 12;
}
return this._num(ctx, hour, min(node[1], 2));
};
CalendarFormatter.prototype.hourAlt = function (ctx, node) {
var date = ctx.date;
var twelve = node[0] === 'K';
var hour = twelve ? date.hour() : date.hourOfDay();
if (!twelve && hour === 0) {
hour = 24;
}
return this._num(ctx, hour, min(node[1], 2));
};
CalendarFormatter.prototype.minute = function (ctx, node) {
return this._num(ctx, ctx.date.minute(), min(node[1], 2));
};
CalendarFormatter.prototype.second = function (ctx, node) {
return this._num(ctx, ctx.date.second(), min(node[1], 2));
};
CalendarFormatter.prototype.fractionalSecond = function (ctx, node) {
var w = node[1];
var m = ctx.date.milliseconds();
var d = w > 3 ? w - 3 : 0;
w -= d;
if (d > 0) {
m *= Math.pow(10, d);
}
// Milliseconds always have precision of 3, so handle the cases compactly.
var n = w === 3 ? m : (w === 2 ? (m / 10) : (m / 100)) | 0;
return this._num(ctx, n, node[1]);
};
CalendarFormatter.prototype.millisInDay = function (ctx, node) {
return this._num(ctx, ctx.date.millisecondsInDay(), node[1]);
};
/**
* Timezone: short/long specific non-location format.
* https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
*/
CalendarFormatter.prototype.timezone_z = function (ctx, node) {
if (node[1] > 4) {
return '';
}
var key2 = ctx.date.metaZoneId();
if (key2) {
var _a = this.tz.metaZones, long = _a.long, short = _a.short;
var format = node[1] === 4 ? long : short;
var name_1 = format.get(ctx.bundle, ctx.date.isDaylightSavings() ? 'daylight' : 'standard', key2);
if (name_1) {
return name_1;
}
}
return this.timezone_O(ctx, node);
};
/**
* Timezone: ISO8601 basic/extended format, long localized GMT format.
* https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
*/
CalendarFormatter.prototype.timezone_Z = function (ctx, node) {
var width = node[1];
if (width === 4) {
return this.timezone_O(ctx, ['O', width]);
}
var _a = getTZC(ctx.date.timeZoneOffset()), _ = _a[0], negative = _a[1], hours = _a[2], minutes = _a[3];
var fmt = '';
if (width <= 5) {
// TODO: use number params
fmt += negative ? '+' : '-';
fmt += this._num(ctx, hours, 2);
if (width === 5) {
fmt += ':';
}
fmt += this._num(ctx, minutes, 2);
}
return fmt;
};
/**
* Timezone: short/long localized GMT format.
*/
CalendarFormatter.prototype.timezone_O = function (ctx, node) {
return node[1] === 1 || node[1] === 4 ? this._wrapGMT(ctx, node[1] === 1) : '';
};
/**
* Timezone: short/long generic non-location format.
*/
CalendarFormatter.prototype.timezone_v = function (ctx, node) {
var width = node[1];
if (width !== 1 && width !== 4) {
return '';
}
var name = '';
var key = ctx.date.metaZoneId();
if (key) {
var _a = this.tz.metaZones, long = _a.long, short = _a.short;
var format = width === 1 ? short : long;
name = format.get(ctx.bundle, 'generic', key);
}
return name ? name : this.timezone_O(ctx, ['O', width]);
};
/**
* Timezone: short/long zone ID, exemplar city, generic location format.
* https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
*/
CalendarFormatter.prototype.timezone_V = function (ctx, node) {
var bundle = ctx.bundle;
var zoneId = ctx.date.timeZoneId();
var exemplarCity = this.tz.exemplarCity;
var city = '';
switch (node[1]) {
case 4:
city = exemplarCity.get(bundle, zoneId);
if (!city) {
return this.timezone_O(ctx, ['O', 4]);
}
var pattern = this.tz.regionFormat.get(bundle);
return this.wrapper.format(pattern, [city]);
case 3:
// Exemplar city for the timezone.
city = exemplarCity.get(bundle, zoneId);
return city ? city : exemplarCity.get(bundle, 'Etc/Unknown');
case 2:
return zoneId;
case 1:
return 'unk';
}
return '';
};
/**
* Timezone: ISO8601 basic format
* https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
*/
CalendarFormatter.prototype.timezone_x = function (ctx, node) {
var field = node[0], width = node[1];
var _a = getTZC(ctx.date.timeZoneOffset()), offset = _a[0], negative = _a[1], hours = _a[2], minutes = _a[3];
var fmt = '';
if (width >= 1 && width <= 5) {
fmt += negative ? '-' : '+';
fmt += this._num(ctx, hours, 2);
if (width === 3 || width === 5) {
fmt += ':';
}
if (width !== 1 || minutes > 0) {
fmt += this._num(ctx, minutes, 2);
}
if (field === 'X' && offset === 0) {
fmt += 'Z';
}
}
return fmt;
};
CalendarFormatter.prototype._wrapGMT = function (ctx, short) {
var bundle = ctx.bundle, date = ctx.date;
var _offset = date.timeZoneOffset();
if (_offset === 0) {
return this.tz.gmtZeroFormat.get(bundle);
}
var _a = getTZC(_offset), offset = _a[0], negative = _a[1], hours = _a[2], minutes = _a[3];
var emitMins = !short || minutes > 0;
var hourPattern = this._hourPattern(bundle, negative);
var fmt = '';
for (var _i = 0, hourPattern_1 = hourPattern; _i < hourPattern_1.length; _i++) {
var n = hourPattern_1[_i];
if (typeof n === 'string') {
var sep = n === '.' || n === ':';
if (!sep || emitMins) {
fmt += n;
}
}
else {
var field = n[0], width = n[1];
if (field === 'H') {
fmt += width === 1 ? this._num(ctx, hours, 1) : this._num(ctx, hours, short ? 1 : width);
}
else if (field === 'm' && emitMins) {
fmt += this._num(ctx, minutes, width);
}
}
}
var wrap = this.tz.gmtFormat.get(bundle);
return this.wrapper.format(wrap, [fmt]);
};
CalendarFormatter.prototype._hourPattern = function (bundle, negative) {
var raw = this.tz.hourFormat.get(bundle);
return this.internals.calendars.getHourPattern(raw, negative);
};
return CalendarFormatter;
}());
exports.CalendarFormatter = CalendarFormatter;
//# sourceMappingURL=formatter.js.map