@akala/core
Version:
182 lines (170 loc) • 6.7 kB
text/typescript
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());