UNPKG

@akala/core

Version:
182 lines (170 loc) 6.7 kB
import { Parser, ParsedString } from "../parser"; import { Formatter, FormatterFactory } from "./common"; import { module } from "../helpers"; export interface DateFormatterSettings { format: string; } var formats = { h: Date.prototype.getUTCHours, m: Date.prototype.getUTCMinutes, y: Date.prototype.getUTCFullYear, M: function (this: Date) { return this.getUTCMonth() + 1; }, d: Date.prototype.getDate, s: Date.prototype.getUTCSeconds } export function formatParser(format: string) { return { format: function (value: Date) { var result: string = ''; var offset = 0; var currentFormat: string; for (var i = offset; i < format.length; i++) { if (i == offset) currentFormat = format[i]; if (currentFormat == format[i]) continue; else { if (currentFormat in formats) { let tmp = formats[currentFormat].call(value); switch (i - offset) { case 1: if (currentFormat == 'y') tmp = tmp % 100; result += tmp; break; case 2: if (currentFormat == 'y') tmp = tmp % 100; if (tmp < 10) result += '0' + tmp; else result += tmp; break; case 4: if (currentFormat == 'y') result += tmp; else throw new Error(`Unsupported format ${format.substring(0, i)}`); break; case 3: default: throw new Error(`Unsupported format ${format.substring(0, i)}`); } } else { result += format.substr(offset, i); } offset = i + 1; } } return result; }, parse: function (value: string) { var result = new Date(0, 0, 0, 0, 0, 0, 0); var formatOffset = 0; var valueOffset = 0; var currentFormat: string; for (var i = formatOffset; i <= format.length; i++) { if (i == formatOffset) currentFormat = format[i]; if (currentFormat == format[i] && currentFormat in formats) continue; else { if (currentFormat in formats) { let tmp: number; if (i == format.length) tmp = Number(value.substring(valueOffset)); else { tmp = Number(value.substring(valueOffset, value.indexOf(format[i], valueOffset))); valueOffset = value.indexOf(format[i], valueOffset) + 1; } if (isNaN(tmp)) throw new Error(`${value} (${value.substring(valueOffset, i)}) does not match ${format}`); if (currentFormat == 'M') tmp--; switch (i - formatOffset) { case 1: case 2: case 4: if (currentFormat == 'y' && tmp < 100) if (tmp < 75) tmp = tmp + 2000; else tmp = tmp + 1900; switch (currentFormat) { case 'h': result.setUTCHours(tmp); break; case 'm': result.setUTCMinutes(tmp); break; case 'y': result.setUTCFullYear(tmp); break; case 'M': result.setUTCMonth(tmp); break; case 'd': result.setUTCDate(tmp); break; case 's': result.setUTCSeconds(tmp); break; } break; case 3: default: throw new Error(`Unsupported format ${format.substring(0, i)}`); } } formatOffset = i + 1; } } return result; } } } export class DateFormatter implements FormatterFactory<Date, DateFormatterSettings> { constructor() { } public parse(expression: string): DateFormatterSettings { // console.log(expression); var settings = Parser.parse(expression); if (settings instanceof ParsedString) return { format: settings.value }; return settings as DateFormatterSettings; } public build(formatter: Formatter<any>, settings: DateFormatterSettings): Formatter<Date> { var parser = formatParser(settings && settings.format || 'yyyy-MM-dd'); return function (value) { value = formatter(value); if (value instanceof Date) return value; if (typeof value != 'string') value = value.toString(); return parser.parse(value); } } } module('$formatters').register('#date', new DateFormatter());