parseIso.js
3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
define(['../array/some'], function (some) {
var datePatterns = [
/^([0-9]{4})$/, // YYYY
/^([0-9]{4})-([0-9]{2})$/, // YYYY-MM (YYYYMM not allowed)
/^([0-9]{4})-?([0-9]{2})-?([0-9]{2})$/ // YYYY-MM-DD or YYYYMMDD
];
var ORD_DATE = /^([0-9]{4})-?([0-9]{3})$/; // YYYY-DDD
var timePatterns = [
/^([0-9]{2}(?:\.[0-9]*)?)$/, // HH.hh
/^([0-9]{2}):?([0-9]{2}(?:\.[0-9]*)?)$/, // HH:MM.mm
/^([0-9]{2}):?([0-9]{2}):?([0-9]{2}(\.[0-9]*)?)$/ // HH:MM:SS.ss
];
var DATE_TIME = /^(.+)T(.+)$/;
var TIME_ZONE = /^(.+)([+\-])([0-9]{2}):?([0-9]{2})$/;
function matchAll(str, patterns) {
var match;
var found = some(patterns, function(pattern) {
return !!(match = pattern.exec(str));
});
return found ? match : null;
}
function getDate(year, month, day) {
var date = new Date(Date.UTC(year, month, day));
// Explicitly set year to avoid Date.UTC making dates < 100 relative to
// 1900
date.setUTCFullYear(year);
var valid =
date.getUTCFullYear() === year &&
date.getUTCMonth() === month &&
date.getUTCDate() === day;
return valid ? +date : NaN;
}
function parseOrdinalDate(str) {
var match = ORD_DATE.exec(str);
if (match ) {
var year = +match[1],
day = +match[2],
date = new Date(Date.UTC(year, 0, day));
if (date.getUTCFullYear() === year) {
return +date;
}
}
return NaN;
}
function parseDate(str) {
var match, year, month, day;
match = matchAll(str, datePatterns);
if (match === null) {
// Ordinal dates are verified differently.
return parseOrdinalDate(str);
}
year = (match[1] === void 0) ? 0 : +match[1];
month = (match[2] === void 0) ? 0 : +match[2] - 1;
day = (match[3] === void 0) ? 1 : +match[3];
return getDate(year, month, day);
}
function getTime(hr, min, sec) {
var valid =
(hr < 24 && hr >= 0 &&
min < 60 && min >= 0 &&
sec < 60 && min >= 0) ||
(hr === 24 && min === 0 && sec === 0);
if (!valid) {
return NaN;
}
return ((hr * 60 + min) * 60 + sec) * 1000;
}
function parseOffset(str) {
var match;
if (str.charAt(str.length - 1) === 'Z') {
str = str.substring(0, str.length - 1);
} else {
match = TIME_ZONE.exec(str);
if (match) {
var hours = +match[3],
minutes = (match[4] === void 0) ? 0 : +match[4],
offset = getTime(hours, minutes, 0);
if (match[2] === '-') {
offset *= -1;
}
return { offset: offset, time: match[1] };
}
}
// No time zone specified, assume UTC
return { offset: 0, time: str };
}
function parseTime(str) {
var match;
var offset = parseOffset(str);
str = offset.time;
offset = offset.offset;
if (isNaN(offset)) {
return NaN;
}
match = matchAll(str, timePatterns);
if (match === null) {
return NaN;
}
var hours = (match[1] === void 0) ? 0 : +match[1],
minutes = (match[2] === void 0) ? 0 : +match[2],
seconds = (match[3] === void 0) ? 0 : +match[3];
return getTime(hours, minutes, seconds) - offset;
}
/**
* Parse an ISO8601 formatted date string, and return a Date object.
*/
function parseISO8601(str){
var match = DATE_TIME.exec(str);
if (!match) {
// No time specified
return parseDate(str);
}
return parseDate(match[1]) + parseTime(match[2]);
}
return parseISO8601;
});