in tapestry-framework/src/js/dojo-0.4.3-custom-4.1.6/dojo2.js.uncompressed.js [2191:2414]
dojo.date.parse = function(/*String*/value, /*Object?*/options){
//
// summary:
// Convert a properly formatted string to a primitive Date object,
// using locale-specific settings.
//
// description:
// Create a Date object from a string using a known localized pattern.
// By default, this method parses looking for both date and time in the string.
// Formatting patterns are chosen appropriate to the locale. Different
// formatting lengths may be chosen, with "full" used by default.
// Custom patterns may be used or registered with translations using
// the addCustomBundle method.
// Formatting patterns are implemented using the syntax described at
// http://www.unicode.org/reports/tr35/#Date_Format_Patterns
//
// value:
// A string representation of a date
//
// options: object {selector: string, formatLength: string, datePattern: string, timePattern: string, locale: string, strict: boolean}
// selector- choice of timeOnly, dateOnly, dateTime (default: dateOnly)
// formatLength- choice of long, short, medium or full (plus any custom additions). Defaults to 'full'
// datePattern,timePattern- override pattern with this string
// am,pm- override strings for am/pm in times
// locale- override the locale used to determine formatting rules
// strict- strict parsing, off by default
//
options = options || {};
var locale = dojo.hostenv.normalizeLocale(options.locale);
var info = dojo.date._getGregorianBundle(locale);
var formatLength = options.formatLength || 'full';
if(!options.selector){ options.selector = 'dateOnly'; }
var datePattern = options.datePattern || info["dateFormat-" + formatLength];
var timePattern = options.timePattern || info["timeFormat-" + formatLength];
var pattern;
if(options.selector == 'dateOnly'){
pattern = datePattern;
}
else if(options.selector == 'timeOnly'){
pattern = timePattern;
}else if(options.selector == 'dateTime'){
pattern = datePattern + ' ' + timePattern; //TODO: use locale-specific pattern to assemble date + time
}else{
var msg = "dojo.date.parse: Unknown selector param passed: '" + options.selector + "'.";
msg += " Defaulting to date pattern.";
dojo.debug(msg);
pattern = datePattern;
}
var groups = [];
var dateREString = _processPattern(pattern, dojo.lang.curry(this, _buildDateTimeRE, groups, info, options));
var dateRE = new RegExp("^" + dateREString + "$");
var match = dateRE.exec(value);
if(!match){
return null;
}
var widthList = ['abbr', 'wide', 'narrow'];
//1972 is a leap year. We want to avoid Feb 29 rolling over into Mar 1,
//in the cases where the year is parsed after the month and day.
var result = new Date(1972, 0);
var expected = {};
for(var i=1; i<match.length; i++){
var grp=groups[i-1];
var l=grp.length;
var v=match[i];
switch(grp.charAt(0)){
case 'y':
if(l != 2){
//interpret year literally, so '5' would be 5 A.D.
result.setFullYear(v);
expected.year = v;
}else{
if(v<100){
v = Number(v);
//choose century to apply, according to a sliding window
//of 80 years before and 20 years after present year
var year = '' + new Date().getFullYear();
var century = year.substring(0, 2) * 100;
var yearPart = Number(year.substring(2, 4));
var cutoff = Math.min(yearPart + 20, 99);
var num = (v < cutoff) ? century + v : century - 100 + v;
result.setFullYear(num);
expected.year = num;
}else{
//we expected 2 digits and got more...
if(options.strict){
return null;
}
//interpret literally, so '150' would be 150 A.D.
//also tolerate '1950', if 'yyyy' input passed to 'yy' format
result.setFullYear(v);
expected.year = v;
}
}
break;
case 'M':
if (l>2) {
if(!options.strict){
//Tolerate abbreviating period in month part
v = v.replace(/\./g,'');
//Case-insensitive
v = v.toLowerCase();
}
var months = info['months-format-' + widthList[l-3]].concat();
for (var j=0; j<months.length; j++){
if(!options.strict){
//Case-insensitive
months[j] = months[j].toLowerCase();
}
if(v == months[j]){
result.setMonth(j);
expected.month = j;
break;
}
}
if(j==months.length){
dojo.debug("dojo.date.parse: Could not parse month name: '" + v + "'.");
return null;
}
}else{
result.setMonth(v-1);
expected.month = v-1;
}
break;
case 'E':
case 'e':
if(!options.strict){
//Case-insensitive
v = v.toLowerCase();
}
var days = info['days-format-' + widthList[l-3]].concat();
for (var j=0; j<days.length; j++){
if(!options.strict){
//Case-insensitive
days[j] = days[j].toLowerCase();
}
if(v == days[j]){
//TODO: not sure what to actually do with this input,
//in terms of setting something on the Date obj...?
//without more context, can't affect the actual date
break;
}
}
if(j==days.length){
dojo.debug("dojo.date.parse: Could not parse weekday name: '" + v + "'.");
return null;
}
break;
case 'd':
result.setDate(v);
expected.date = v;
break;
case 'a': //am/pm
var am = options.am || info.am;
var pm = options.pm || info.pm;
if(!options.strict){
v = v.replace(/\./g,'').toLowerCase();
am = am.replace(/\./g,'').toLowerCase();
pm = pm.replace(/\./g,'').toLowerCase();
}
if(options.strict && v != am && v != pm){
dojo.debug("dojo.date.parse: Could not parse am/pm part.");
return null;
}
var hours = result.getHours();
if(v == pm && hours < 12){
result.setHours(hours + 12); //e.g., 3pm -> 15
} else if(v == am && hours == 12){
result.setHours(0); //12am -> 0
}
break;
case 'K': //hour (1-24)
if(v==24){v=0;}
// fallthrough...
case 'h': //hour (1-12)
case 'H': //hour (0-23)
case 'k': //hour (0-11)
//TODO: strict bounds checking, padding
if(v>23){
dojo.debug("dojo.date.parse: Illegal hours value");
return null;
}
//in the 12-hour case, adjusting for am/pm requires the 'a' part
//which for now we will assume always comes after the 'h' part
result.setHours(v);
break;
case 'm': //minutes
result.setMinutes(v);
break;
case 's': //seconds
result.setSeconds(v);
break;
case 'S': //milliseconds
result.setMilliseconds(v);
break;
default:
dojo.unimplemented("dojo.date.parse: unsupported pattern char=" + grp.charAt(0));
}
}
//validate parse date fields versus input date fields
if(expected.year && result.getFullYear() != expected.year){
dojo.debug("Parsed year: '" + result.getFullYear() + "' did not match input year: '" + expected.year + "'.");
return null;
}
if(expected.month && result.getMonth() != expected.month){
dojo.debug("Parsed month: '" + result.getMonth() + "' did not match input month: '" + expected.month + "'.");
return null;
}
if(expected.date && result.getDate() != expected.date){
dojo.debug("Parsed day of month: '" + result.getDate() + "' did not match input day of month: '" + expected.date + "'.");
return null;
}
//TODO: implement a getWeekday() method in order to test
//validity of input strings containing 'EEE' or 'EEEE'...
return result; /*Date*/
};