blob: 59abf55bac1b424cfe0072d2a7dfffec42bde8da [file] [log] [blame]
"use strict";
function padWithZeros(vNumber, width) {
var numAsString = vNumber.toString();
while (numAsString.length < width) {
numAsString = "0" + numAsString;
}
return numAsString;
}
function addZero(vNumber) {
return padWithZeros(vNumber, 2);
}
/**
* Formats the TimeOffset
* Thanks to http://www.svendtofte.com/code/date_format/
* @private
*/
function offset(timezoneOffset) {
var os = Math.abs(timezoneOffset);
var h = String(Math.floor(os / 60));
var m = String(os % 60);
if (h.length === 1) {
h = "0" + h;
}
if (m.length === 1) {
m = "0" + m;
}
return timezoneOffset < 0 ? "+" + h + m : "-" + h + m;
}
function datePart(date, displayUTC, part) {
return displayUTC ? date["getUTC" + part]() : date["get" + part]();
}
function asString(format, date) {
if (typeof format !== "string") {
date = format;
format = module.exports.ISO8601_FORMAT;
}
if (!date) {
date = module.exports.now();
}
var displayUTC = format.indexOf("O") > -1;
var vDay = addZero(datePart(date, displayUTC, "Date"));
var vMonth = addZero(datePart(date, displayUTC, "Month") + 1);
var vYearLong = addZero(datePart(date, displayUTC, "FullYear"));
var vYearShort = addZero(vYearLong.substring(2, 4));
var vYear = format.indexOf("yyyy") > -1 ? vYearLong : vYearShort;
var vHour = addZero(datePart(date, displayUTC, "Hours"));
var vMinute = addZero(datePart(date, displayUTC, "Minutes"));
var vSecond = addZero(datePart(date, displayUTC, "Seconds"));
var vMillisecond = padWithZeros(
datePart(date, displayUTC, "Milliseconds"),
3
);
var vTimeZone = offset(date.getTimezoneOffset());
var formatted = format
.replace(/dd/g, vDay)
.replace(/MM/g, vMonth)
.replace(/y{1,4}/g, vYear)
.replace(/hh/g, vHour)
.replace(/mm/g, vMinute)
.replace(/ss/g, vSecond)
.replace(/SSS/g, vMillisecond)
.replace(/O/g, vTimeZone);
return formatted;
}
function extractDateParts(pattern, str, missingValuesDate) {
var matchers = [
{
pattern: /y{1,4}/,
regexp: "\\d{1,4}",
fn: function(date, value) {
date.setFullYear(value);
}
},
{
pattern: /MM/,
regexp: "\\d{1,2}",
fn: function(date, value) {
date.setMonth(value - 1);
}
},
{
pattern: /dd/,
regexp: "\\d{1,2}",
fn: function(date, value) {
date.setDate(value);
}
},
{
pattern: /hh/,
regexp: "\\d{1,2}",
fn: function(date, value) {
date.setHours(value);
}
},
{
pattern: /mm/,
regexp: "\\d\\d",
fn: function(date, value) {
date.setMinutes(value);
}
},
{
pattern: /ss/,
regexp: "\\d\\d",
fn: function(date, value) {
date.setSeconds(value);
}
},
{
pattern: /SSS/,
regexp: "\\d\\d\\d",
fn: function(date, value) {
date.setMilliseconds(value);
}
},
{
pattern: /O/,
regexp: "[+-]\\d{3,4}|Z",
fn: function(date, value) {
if (value === "Z") {
value = 0;
}
var offset = Math.abs(value);
var minutes = (offset % 100) + Math.floor(offset / 100) * 60;
date.setMinutes(date.getMinutes() + (value > 0 ? minutes : -minutes));
}
}
];
var parsedPattern = matchers.reduce(
function(p, m) {
if (m.pattern.test(p.regexp)) {
m.index = p.regexp.match(m.pattern).index;
p.regexp = p.regexp.replace(m.pattern, "(" + m.regexp + ")");
} else {
m.index = -1;
}
return p;
},
{ regexp: pattern, index: [] }
);
var dateFns = matchers.filter(function(m) {
return m.index > -1;
});
dateFns.sort(function(a, b) {
return a.index - b.index;
});
var matcher = new RegExp(parsedPattern.regexp);
var matches = matcher.exec(str);
if (matches) {
var date = missingValuesDate || module.exports.now();
dateFns.forEach(function(f, i) {
f.fn(date, matches[i + 1]);
});
return date;
}
throw new Error(
"String '" + str + "' could not be parsed as '" + pattern + "'"
);
}
function parse(pattern, str, missingValuesDate) {
if (!pattern) {
throw new Error("pattern must be supplied");
}
return extractDateParts(pattern, str, missingValuesDate);
}
/**
* Used for testing - replace this function with a fixed date.
*/
function now() {
return new Date();
}
module.exports = asString;
module.exports.asString = asString;
module.exports.parse = parse;
module.exports.now = now;
module.exports.ISO8601_FORMAT = "yyyy-MM-ddThh:mm:ss.SSS";
module.exports.ISO8601_WITH_TZ_OFFSET_FORMAT = "yyyy-MM-ddThh:mm:ss.SSSO";
module.exports.DATETIME_FORMAT = "dd MM yyyy hh:mm:ss.SSS";
module.exports.ABSOLUTETIME_FORMAT = "hh:mm:ss.SSS";