Added handling of show work units in fav reports and export / import.
[timetracker.git] / js / strptime.js
1 // http://www.logilab.org/blogentry/6731
2 // modified to parse formats with unsupported chars and make compatible with IE7
3
4 var _DATE_FORMAT_REGXES = {
5     'Y': new RegExp('^-?[0-9]+'),
6     'd': new RegExp('^[0-9]{1,2}'),
7     'm': new RegExp('^[0-9]{1,2}'),
8     'H': new RegExp('^[0-9]{1,2}'),
9     'M': new RegExp('^[0-9]{1,2}')
10 }
11
12 /*
13  * _parseData does the actual parsing job needed by `strptime`
14  */
15 function _parseDate(datestring, format) {
16   var skip0 = new RegExp('^0*[0-9]+');
17   var skipRE = new RegExp('^.+?(\\s|$)');
18   var parsed = {};  
19   for (var i1=0,i2=0;i1<format.length;i1++,i2++) {
20     var c1 = format.charAt(i1);
21     var c2 = datestring.charAt(i2);   
22     
23     if (c1 == '%') {
24         c1 = format.charAt(++i1);
25         
26         var data;        
27         if(c1 in _DATE_FORMAT_REGXES) {
28           data = _DATE_FORMAT_REGXES[c1].exec(datestring.substring(i2));          
29         } else {
30           // skip text that are not parsed
31           skip = skipRE.exec(datestring.substring(i2));
32           //alert(datestring.substring(i2) + ':' + skip);
33           i2 += skip[0].length-2;          
34           continue;
35         }
36         if (!data || !data.length) {          
37           return null;
38         }
39         data = data[0];
40         i2 += data.length-1;
41         var value = parseInt(data, 10);
42         if (isNaN(value)) {
43           
44           return null;
45         }
46         parsed[c1] = value;
47         continue;
48     }
49     if (c1 != c2) {      
50       return null;
51     }
52   }  
53   return parsed;
54 }
55
56 /*
57  * basic implementation of strptime. The only recognized formats
58  * defined in _DATE_FORMAT_REGEXES (i.e. %Y, %d, %m, %H, %M)
59  */
60 function strptime(datestring, format) {
61     var parsed = _parseDate(datestring, format);    
62     if (!parsed) {
63     return null;
64     }
65     
66     // create initial date (!!! year=0 means 1900 !!!)
67     var date = new Date(0, 0, 1, 0, 0);
68     date.setFullYear(0); // reset to year 0
69     if (parsed.Y) {
70     date.setFullYear(parsed.Y);
71     }
72     if (parsed.m) {
73     if (parsed.m < 1 || parsed.m > 12) {
74         return null;
75     }
76     // !!! month indexes start at 0 in javascript !!!
77     date.setMonth(parsed.m - 1);
78     }
79     if (parsed.d) {
80     if (parsed.m < 1 || parsed.m > 31) {
81         return null;
82     }
83     date.setDate(parsed.d);
84     }
85     if (parsed.H) {
86     if (parsed.H < 0 || parsed.H > 23) {
87         return null;
88     }
89     date.setHours(parsed.H);
90     }
91     if (parsed.M) {
92     if (parsed.M < 0 || parsed.M > 59) {
93         return null;
94     }
95     date.setMinutes(parsed.M);
96     }
97     return date;
98 }
99
100 // and now monkey patch the Timeline's parser ...
101 /*
102  * provide our own custom date parser since the default one only understands
103  * iso8601 and gregorian dates
104  */
105 /*
106  * Timeline.NativeDateUnit.getParser = function(format) { if (typeof format ==
107  * "string") { if (format.indexOf('%') != -1) { return function(datestring) { if
108  * (datestring) { return strptime(datestring, format); } return null; }; }
109  * format = format.toLowerCase(); } if (format == "iso8601" || format == "iso
110  * 8601") { return Timeline.DateTime.parseIso8601DateTime; } return
111  * Timeline.DateTime.parseGregorianDateTime; };
112  */