1 Date._parseExact = function Date$_parseExact(value, format, cultureInfo) {
2 value = value.trim();
3 var dtf = cultureInfo.dateTimeFormat;
4 var parseInfo = Date._getParseRegExp(dtf, format);
5 var match = new RegExp(parseInfo.regExp).exec(value);
6 if (match === null) return null;
7
8 var groups = parseInfo.groups;
9 var year = null, month = null, date = null, weekDay = null;
10 var hour = 0, min = 0, sec = 0, msec = 0, tzMinOffset = null;
11 var pmHour = false;
12 for (var j = 0, jl = groups.length; j < jl; j++) {
13 var matchGroup = match[j+1];
14 if (matchGroup) {
15 switch (groups[j]) {
16 case 'dd': case 'd':
17 date = parseInt(matchGroup, 10);
18 if ((date < 1) || (date > 31)) return null;
19 break;
20 case 'MMMM':
21 month = cultureInfo._getMonthIndex(matchGroup);
22 if ((month < 0) || (month > 11)) return null;
23 break;
24 case 'MMM':
25 month = cultureInfo._getAbbrMonthIndex(matchGroup);
26 if ((month < 0) || (month > 11)) return null;
27 break;
28 case 'M': case 'MM':
29 var month = parseInt(matchGroup, 10) - 1;
30 if ((month < 0) || (month > 11)) return null;
31 break;
32 case 'y': case 'yy':
33 year = Date._expandYear(dtf,parseInt(matchGroup, 10));
34 if ((year < 0) || (year > 9999)) return null;
35 break;
36 case 'yyyy':
37 year = parseInt(matchGroup, 10);
38 if ((year < 0) || (year > 9999)) return null;
39 break;
40 case 'h': case 'hh':
41 hour = parseInt(matchGroup, 10);
42 if (hour === 12) hour = 0;
43 if ((hour < 0) || (hour > 11)) return null;
44 break;
45 case 'H': case 'HH':
46 hour = parseInt(matchGroup, 10);
47 if ((hour < 0) || (hour > 23)) return null;
48 break;
49 case 'm': case 'mm':
50 min = parseInt(matchGroup, 10);
51 if ((min < 0) || (min > 59)) return null;
52 break;
53 case 's': case 'ss':
54 sec = parseInt(matchGroup, 10);
55 if ((sec < 0) || (sec > 59)) return null;
56 break;
57 case 'tt': case 't':
58 var upperToken = matchGroup.toUpperCase();
59 pmHour = (upperToken === dtf.PMDesignator.toUpperCase());
60 if (!pmHour && (upperToken !== dtf.AMDesignator.toUpperCase())) return null;
61 break;
62 case 'f':
63 msec = parseInt(matchGroup, 10) * 100;
64 if ((msec < 0) || (msec > 999)) return null;
65 break;
66 case 'ff':
67 msec = parseInt(matchGroup, 10) * 10;
68 if ((msec < 0) || (msec > 999)) return null;
69 break;
70 case 'fff':
71 msec = parseInt(matchGroup, 10);
72 if ((msec < 0) || (msec > 999)) return null;
73 break;
74 case 'dddd':
75 weekDay = cultureInfo._getDayIndex(matchGroup);
76 if ((weekDay < 0) || (weekDay > 6)) return null;
77 break;
78 case 'ddd':
79 weekDay = cultureInfo._getAbbrDayIndex(matchGroup);
80 if ((weekDay < 0) || (weekDay > 6)) return null;
81 break;
82 case 'zzz':
83 var offsets = matchGroup.split(/:/);
84 if (offsets.length !== 2) return null;
85 var hourOffset = parseInt(offsets[0], 10);
86 if ((hourOffset < -12) || (hourOffset > 13)) return null;
87 var minOffset = parseInt(offsets[1], 10);
88 if ((minOffset < 0) || (minOffset > 59)) return null;
89 tzMinOffset = (hourOffset * 60) + (matchGroup.startsWith('-')? -minOffset : minOffset);
90 break;
91 case 'z': case 'zz':
92 var hourOffset = parseInt(matchGroup, 10);
93 if ((hourOffset < -12) || (hourOffset > 13)) return null;
94 tzMinOffset = hourOffset * 60;
95 break;
96 }
97 }
98 }
99 var result = new Date();
100 if (year === null) {
101 year = result.getFullYear();
102 }
103 if (month === null) {
104 month = result.getMonth();
105 }
106 if (date === null) {
107 date = result.getDate();
108 }
109 result.setFullYear(year, month, date);
110 if (result.getDate() !== date) return null;
111 if ((weekDay !== null) && (result.getDay() !== weekDay)) {
112 return null;
113 }
114 if (pmHour && (hour < 12)) {
115 hour += 12;
116 }
117 result.setHours(hour, min, sec, msec);
118 if (tzMinOffset !== null) {
119 var adjustedMin = result.getMinutes() - (tzMinOffset + result.getTimezoneOffset());
120 result.setHours(result.getHours() + parseInt(adjustedMin/60, 10), adjustedMin%60);
121 }
122 return result;
123 }