145 lines
4.0 KiB
TypeScript
Raw Normal View History

// Modified version of internal Typescript intl.d.ts.
// TODO(piloopin): remove when https://github.com/Microsoft/TypeScript/issues/3521 is shipped.
declare module Intl {
interface NumberFormatOptions {
localeMatcher?: string;
style?: string;
currency?: string;
currencyDisplay?: string;
useGrouping?: boolean;
}
interface NumberFormat {
format(value: number): string;
}
var NumberFormat: { new (locale?: string, options?: NumberFormatOptions): NumberFormat; }
interface DateTimeFormatOptions {
localeMatcher?: string;
weekday?: string;
era?: string;
year?: string;
month?: string;
day?: string;
hour?: string;
minute?: string;
second?: string;
timeZoneName?: string;
formatMatcher?: string;
hour12?: boolean;
}
interface DateTimeFormat {
format(date?: Date | number): string;
}
var DateTimeFormat: { new (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; }
}
export enum NumberFormatStyle {
DECIMAL,
PERCENT,
CURRENCY
}
export class NumberFormatter {
static format(number: number, locale: string, style: NumberFormatStyle,
{minimumIntegerDigits = 1, minimumFractionDigits = 0, maximumFractionDigits = 3,
currency, currencyAsSymbol = false}: {
minimumIntegerDigits?: int,
minimumFractionDigits?: int,
maximumFractionDigits?: int,
currency?: string,
currencyAsSymbol?: boolean
} = {}): string {
var intlOptions: Intl.NumberFormatOptions = {
minimumIntegerDigits: minimumIntegerDigits,
minimumFractionDigits: minimumFractionDigits,
maximumFractionDigits: maximumFractionDigits
};
intlOptions.style = NumberFormatStyle[style].toLowerCase();
if (style == NumberFormatStyle.CURRENCY) {
intlOptions.currency = currency;
intlOptions.currencyDisplay = currencyAsSymbol ? 'symbol' : 'code';
}
return new Intl.NumberFormat(locale, intlOptions).format(number);
}
}
function digitCondition(len: int): string {
return len == 2 ? '2-digit' : 'numeric';
}
function nameCondition(len: int): string {
return len < 4 ? 'short' : 'long';
}
function extractComponents(pattern: string): Intl.DateTimeFormatOptions {
var ret: Intl.DateTimeFormatOptions = {};
var i = 0, j;
while (i < pattern.length) {
j = i;
while (j < pattern.length && pattern[j] == pattern[i]) j++;
let len = j - i;
switch (pattern[i]) {
case 'G':
ret.era = nameCondition(len);
break;
case 'y':
ret.year = digitCondition(len);
break;
case 'M':
if (len >= 3)
ret.month = nameCondition(len);
else
ret.month = digitCondition(len);
break;
case 'd':
ret.day = digitCondition(len);
break;
case 'E':
ret.weekday = nameCondition(len);
break;
case 'j':
ret.hour = digitCondition(len);
break;
case 'h':
ret.hour = digitCondition(len);
ret.hour12 = true;
break;
case 'H':
ret.hour = digitCondition(len);
ret.hour12 = false;
break;
case 'm':
ret.minute = digitCondition(len);
break;
case 's':
ret.second = digitCondition(len);
break;
case 'z':
ret.timeZoneName = 'long';
break;
case 'Z':
ret.timeZoneName = 'short';
break;
}
i = j;
}
return ret;
}
var dateFormatterCache: Map<string, Intl.DateTimeFormat> = new Map<string, Intl.DateTimeFormat>();
export class DateFormatter {
static format(date: Date, locale: string, pattern: string): string {
var key = locale + pattern;
if (dateFormatterCache.has(key)) {
return dateFormatterCache.get(key).format(date);
}
var formatter = new Intl.DateTimeFormat(locale, extractComponents(pattern));
dateFormatterCache.set(key, formatter);
return formatter.format(date);
}
}