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