META-INF.resources.bower_components.globalize.src.date.parse.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jwebmp-globalize Show documentation
Show all versions of jwebmp-globalize Show documentation
The JWebSwing implementation for a full Globalization
define([
"./is-leap-year",
"./last-day-of-month",
"./pattern-re",
"./start-of",
"../common/create-error/unsupported-feature",
"../util/date/set-month",
"../util/out-of-range"
], function (dateIsLeapYear, dateLastDayOfMonth, datePatternRe, dateStartOf,
createErrorUnsupportedFeature, dateSetMonth, outOfRange) {
/**
* parse( value, tokens, properties )
*
* @value [String] string date.
*
* @tokens [Object] tokens returned by date/tokenizer.
*
* @properties [Object] output returned by date/tokenizer-properties.
*
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
*/
return function (value, tokens, properties) {
var amPm, day, daysOfYear, month, era, hour, hour12, timezoneOffset, valid,
YEAR = 0,
MONTH = 1,
DAY = 2,
HOUR = 3,
MINUTE = 4,
SECOND = 5,
MILLISECONDS = 6,
date = new Date(),
truncateAt = [],
units = ["year", "month", "day", "hour", "minute", "second", "milliseconds"];
if (!tokens.length) {
return null;
}
valid = tokens.every(function (token) {
var century, chr, value, length;
if (token.type === "literal") {
// continue
return true;
}
chr = token.type.charAt(0);
length = token.type.length;
if (chr === "j") {
// Locale preferred hHKk.
// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
chr = properties.preferredTimeData;
}
switch (chr) {
// Era
case "G":
truncateAt.push(YEAR);
era = +token.value;
break;
// Year
case "y":
value = token.value;
if (length === 2) {
if (outOfRange(value, 0, 99)) {
return false;
}
// mimic dojo/date/locale: choose century to apply, according to a sliding
// window of 80 years before and 20 years after present year.
century = Math.floor(date.getFullYear() / 100) * 100;
value += century;
if (value > date.getFullYear() + 20) {
value -= 100;
}
}
date.setFullYear(value);
truncateAt.push(YEAR);
break;
case "Y": // Year in "Week of Year"
throw createErrorUnsupportedFeature({
feature: "year pattern `" + chr + "`"
});
// Quarter (skip)
case "Q":
case "q":
break;
// Month
case "M":
case "L":
if (length <= 2) {
value = token.value;
} else {
value = +token.value;
}
if (outOfRange(value, 1, 12)) {
return false;
}
// Setting the month later so that we have the correct year and can determine
// the correct last day of February in case of leap year.
month = value;
truncateAt.push(MONTH);
break;
// Week (skip)
case "w": // Week of Year.
case "W": // Week of Month.
break;
// Day
case "d":
day = token.value;
truncateAt.push(DAY);
break;
case "D":
daysOfYear = token.value;
truncateAt.push(DAY);
break;
case "F":
// Day of Week in month. eg. 2nd Wed in July.
// Skip
break;
// Week day
case "e":
case "c":
case "E":
// Skip.
// value = arrayIndexOf( dateWeekDays, token.value );
break;
// Period (AM or PM)
case "a":
amPm = token.value;
break;
// Hour
case "h": // 1-12
value = token.value;
if (outOfRange(value, 1, 12)) {
return false;
}
hour = hour12 = true;
date.setHours(value === 12 ? 0 : value);
truncateAt.push(HOUR);
break;
case "K": // 0-11
value = token.value;
if (outOfRange(value, 0, 11)) {
return false;
}
hour = hour12 = true;
date.setHours(value);
truncateAt.push(HOUR);
break;
case "k": // 1-24
value = token.value;
if (outOfRange(value, 1, 24)) {
return false;
}
hour = true;
date.setHours(value === 24 ? 0 : value);
truncateAt.push(HOUR);
break;
case "H": // 0-23
value = token.value;
if (outOfRange(value, 0, 23)) {
return false;
}
hour = true;
date.setHours(value);
truncateAt.push(HOUR);
break;
// Minute
case "m":
value = token.value;
if (outOfRange(value, 0, 59)) {
return false;
}
date.setMinutes(value);
truncateAt.push(MINUTE);
break;
// Second
case "s":
value = token.value;
if (outOfRange(value, 0, 59)) {
return false;
}
date.setSeconds(value);
truncateAt.push(SECOND);
break;
case "A":
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
/* falls through */
case "S":
value = Math.round(token.value * Math.pow(10, 3 - length));
date.setMilliseconds(value);
truncateAt.push(MILLISECONDS);
break;
// Zone
case "Z":
case "z":
case "O":
case "X":
case "x":
timezoneOffset = token.value;
break;
}
return true;
});
if (!valid) {
return null;
}
// 12-hour format needs AM or PM, 24-hour format doesn't, ie. return null
// if amPm && !hour12 || !amPm && hour12.
if (hour && !(!amPm ^ hour12)) {
return null;
}
if (era === 0) {
// 1 BC = year 0
date.setFullYear(date.getFullYear() * -1 + 1);
}
if (month !== undefined) {
dateSetMonth(date, month - 1);
}
if (day !== undefined) {
if (outOfRange(day, 1, dateLastDayOfMonth(date))) {
return null;
}
date.setDate(day);
} else if (daysOfYear !== undefined) {
if (outOfRange(daysOfYear, 1, dateIsLeapYear(date.getFullYear()) ? 366 : 365)) {
return null;
}
date.setMonth(0);
date.setDate(daysOfYear);
}
if (hour12 && amPm === "pm") {
date.setHours(date.getHours() + 12);
}
if (timezoneOffset !== undefined) {
date.setMinutes(date.getMinutes() + timezoneOffset - date.getTimezoneOffset());
}
// Truncate date at the most precise unit defined. Eg.
// If value is "12/31", and pattern is "MM/dd":
// => new Date( , 12, 31, 0, 0, 0, 0 );
truncateAt = Math.max.apply(null, truncateAt);
date = dateStartOf(date, units[truncateAt]);
return date;
};
});