Mercurial > hg > extraction-interface
comparison geotemco/lib/simile/ajax/scripts/date-time.js @ 0:b12c99b7c3f0
commit for previous development
author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
---|---|
date | Mon, 19 Jan 2015 17:13:49 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b12c99b7c3f0 |
---|---|
1 /** | |
2 * @fileOverview A collection of date/time utility functions | |
3 * @name SimileAjax.DateTime | |
4 */ | |
5 | |
6 SimileAjax.DateTime = new Object(); | |
7 | |
8 SimileAjax.DateTime.MILLISECOND = 0; | |
9 SimileAjax.DateTime.SECOND = 1; | |
10 SimileAjax.DateTime.MINUTE = 2; | |
11 SimileAjax.DateTime.HOUR = 3; | |
12 SimileAjax.DateTime.DAY = 4; | |
13 SimileAjax.DateTime.WEEK = 5; | |
14 SimileAjax.DateTime.MONTH = 6; | |
15 SimileAjax.DateTime.YEAR = 7; | |
16 SimileAjax.DateTime.DECADE = 8; | |
17 SimileAjax.DateTime.CENTURY = 9; | |
18 SimileAjax.DateTime.MILLENNIUM = 10; | |
19 | |
20 SimileAjax.DateTime.EPOCH = -1; | |
21 SimileAjax.DateTime.ERA = -2; | |
22 | |
23 /** | |
24 * An array of unit lengths, expressed in milliseconds, of various lengths of | |
25 * time. The array indices are predefined and stored as properties of the | |
26 * SimileAjax.DateTime object, e.g. SimileAjax.DateTime.YEAR. | |
27 * @type Array | |
28 */ | |
29 SimileAjax.DateTime.gregorianUnitLengths = []; | |
30 (function() { | |
31 var d = SimileAjax.DateTime; | |
32 var a = d.gregorianUnitLengths; | |
33 | |
34 a[d.MILLISECOND] = 1; | |
35 a[d.SECOND] = 1000; | |
36 a[d.MINUTE] = a[d.SECOND] * 60; | |
37 a[d.HOUR] = a[d.MINUTE] * 60; | |
38 a[d.DAY] = a[d.HOUR] * 24; | |
39 a[d.WEEK] = a[d.DAY] * 7; | |
40 a[d.MONTH] = a[d.DAY] * 31; | |
41 a[d.YEAR] = a[d.DAY] * 365; | |
42 a[d.DECADE] = a[d.YEAR] * 10; | |
43 a[d.CENTURY] = a[d.YEAR] * 100; | |
44 a[d.MILLENNIUM] = a[d.YEAR] * 1000; | |
45 })(); | |
46 | |
47 SimileAjax.DateTime._dateRegexp = new RegExp( | |
48 "^(-?)([0-9]{4})(" + [ | |
49 "(-?([0-9]{2})(-?([0-9]{2}))?)", // -month-dayOfMonth | |
50 "(-?([0-9]{3}))", // -dayOfYear | |
51 "(-?W([0-9]{2})(-?([1-7]))?)" // -Wweek-dayOfWeek | |
52 ].join("|") + ")?$" | |
53 ); | |
54 SimileAjax.DateTime._timezoneRegexp = new RegExp( | |
55 "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$" | |
56 ); | |
57 SimileAjax.DateTime._timeRegexp = new RegExp( | |
58 "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$" | |
59 ); | |
60 | |
61 /** | |
62 * Takes a date object and a string containing an ISO 8601 date and sets the | |
63 * the date using information parsed from the string. Note that this method | |
64 * does not parse any time information. | |
65 * | |
66 * @param {Date} dateObject the date object to modify | |
67 * @param {String} string an ISO 8601 string to parse | |
68 * @return {Date} the modified date object | |
69 */ | |
70 SimileAjax.DateTime.setIso8601Date = function(dateObject, string) { | |
71 /* | |
72 * This function has been adapted from dojo.date, v.0.3.0 | |
73 * http://dojotoolkit.org/. | |
74 */ | |
75 | |
76 var d = string.match(SimileAjax.DateTime._dateRegexp); | |
77 if(!d) { | |
78 throw new Error("Invalid date string: " + string); | |
79 } | |
80 | |
81 var sign = (d[1] == "-") ? -1 : 1; // BC or AD | |
82 var year = sign * d[2]; | |
83 var month = d[5]; | |
84 var date = d[7]; | |
85 var dayofyear = d[9]; | |
86 var week = d[11]; | |
87 var dayofweek = (d[13]) ? d[13] : 1; | |
88 | |
89 dateObject.setUTCFullYear(year); | |
90 if (dayofyear) { | |
91 dateObject.setUTCMonth(0); | |
92 dateObject.setUTCDate(Number(dayofyear)); | |
93 } else if (week) { | |
94 dateObject.setUTCMonth(0); | |
95 dateObject.setUTCDate(1); | |
96 var gd = dateObject.getUTCDay(); | |
97 var day = (gd) ? gd : 7; | |
98 var offset = Number(dayofweek) + (7 * Number(week)); | |
99 | |
100 if (day <= 4) { | |
101 dateObject.setUTCDate(offset + 1 - day); | |
102 } else { | |
103 dateObject.setUTCDate(offset + 8 - day); | |
104 } | |
105 } else { | |
106 if (month) { | |
107 dateObject.setUTCDate(1); | |
108 dateObject.setUTCMonth(month - 1); | |
109 } | |
110 if (date) { | |
111 dateObject.setUTCDate(date); | |
112 } | |
113 } | |
114 | |
115 return dateObject; | |
116 }; | |
117 | |
118 /** | |
119 * Takes a date object and a string containing an ISO 8601 time and sets the | |
120 * the time using information parsed from the string. Note that this method | |
121 * does not parse any date information. | |
122 * | |
123 * @param {Date} dateObject the date object to modify | |
124 * @param {String} string an ISO 8601 string to parse | |
125 * @return {Date} the modified date object | |
126 */ | |
127 SimileAjax.DateTime.setIso8601Time = function (dateObject, string) { | |
128 /* | |
129 * This function has been adapted from dojo.date, v.0.3.0 | |
130 * http://dojotoolkit.org/. | |
131 */ | |
132 | |
133 var d = string.match(SimileAjax.DateTime._timeRegexp); | |
134 if(!d) { | |
135 SimileAjax.Debug.warn("Invalid time string: " + string); | |
136 return false; | |
137 } | |
138 var hours = d[1]; | |
139 var mins = Number((d[3]) ? d[3] : 0); | |
140 var secs = (d[5]) ? d[5] : 0; | |
141 var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0; | |
142 | |
143 dateObject.setUTCHours(hours); | |
144 dateObject.setUTCMinutes(mins); | |
145 dateObject.setUTCSeconds(secs); | |
146 dateObject.setUTCMilliseconds(ms); | |
147 | |
148 return dateObject; | |
149 }; | |
150 | |
151 /** | |
152 * The timezone offset in minutes in the user's browser. | |
153 * @type Number | |
154 */ | |
155 SimileAjax.DateTime.timezoneOffset = new Date().getTimezoneOffset(); | |
156 | |
157 /** | |
158 * Takes a date object and a string containing an ISO 8601 date and time and | |
159 * sets the date object using information parsed from the string. | |
160 * | |
161 * @param {Date} dateObject the date object to modify | |
162 * @param {String} string an ISO 8601 string to parse | |
163 * @return {Date} the modified date object | |
164 */ | |
165 SimileAjax.DateTime.setIso8601 = function (dateObject, string){ | |
166 /* | |
167 * This function has been adapted from dojo.date, v.0.3.0 | |
168 * http://dojotoolkit.org/. | |
169 */ | |
170 | |
171 var offset = null; | |
172 var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T"); | |
173 | |
174 SimileAjax.DateTime.setIso8601Date(dateObject, comps[0]); | |
175 if (comps.length == 2) { | |
176 // first strip timezone info from the end | |
177 var d = comps[1].match(SimileAjax.DateTime._timezoneRegexp); | |
178 if (d) { | |
179 if (d[0] == 'Z') { | |
180 offset = 0; | |
181 } else { | |
182 offset = (Number(d[3]) * 60) + Number(d[5]); | |
183 offset *= ((d[2] == '-') ? 1 : -1); | |
184 } | |
185 comps[1] = comps[1].substr(0, comps[1].length - d[0].length); | |
186 } | |
187 | |
188 SimileAjax.DateTime.setIso8601Time(dateObject, comps[1]); | |
189 } | |
190 if (offset == null) { | |
191 offset = dateObject.getTimezoneOffset(); // local time zone if no tz info | |
192 } | |
193 dateObject.setTime(dateObject.getTime() + offset * 60000); | |
194 | |
195 return dateObject; | |
196 }; | |
197 | |
198 /** | |
199 * Takes a string containing an ISO 8601 date and returns a newly instantiated | |
200 * date object with the parsed date and time information from the string. | |
201 * | |
202 * @param {String} string an ISO 8601 string to parse | |
203 * @return {Date} a new date object created from the string | |
204 */ | |
205 SimileAjax.DateTime.parseIso8601DateTime = function (string) { | |
206 try { | |
207 return SimileAjax.DateTime.setIso8601(new Date(0), string); | |
208 } catch (e) { | |
209 return null; | |
210 } | |
211 }; | |
212 | |
213 /** | |
214 * Takes a string containing a Gregorian date and time and returns a newly | |
215 * instantiated date object with the parsed date and time information from the | |
216 * string. If the param is actually an instance of Date instead of a string, | |
217 * simply returns the given date instead. | |
218 * | |
219 * @param {Object} o an object, to either return or parse as a string | |
220 * @return {Date} the date object | |
221 */ | |
222 SimileAjax.DateTime.parseGregorianDateTime = function(o) { | |
223 if (o == null) { | |
224 return null; | |
225 } else if (o instanceof Date) { | |
226 return o; | |
227 } | |
228 | |
229 var s = o.toString(); | |
230 if (s.length > 0 && s.length < 8) { | |
231 var space = s.indexOf(" "); | |
232 if (space > 0) { | |
233 var year = parseInt(s.substr(0, space)); | |
234 var suffix = s.substr(space + 1); | |
235 if (suffix.toLowerCase() == "bc") { | |
236 year = 1 - year; | |
237 } | |
238 } else { | |
239 var year = parseInt(s); | |
240 } | |
241 | |
242 var d = new Date(0); | |
243 d.setUTCFullYear(year); | |
244 | |
245 return d; | |
246 } | |
247 | |
248 try { | |
249 return new Date(Date.parse(s)); | |
250 } catch (e) { | |
251 return null; | |
252 } | |
253 }; | |
254 | |
255 /** | |
256 * Rounds date objects down to the nearest interval or multiple of an interval. | |
257 * This method modifies the given date object, converting it to the given | |
258 * timezone if specified. | |
259 * | |
260 * @param {Date} date the date object to round | |
261 * @param {Number} intervalUnit a constant, integer index specifying an | |
262 * interval, e.g. SimileAjax.DateTime.HOUR | |
263 * @param {Number} timeZone a timezone shift, given in hours | |
264 * @param {Number} multiple a multiple of the interval to round by | |
265 * @param {Number} firstDayOfWeek an integer specifying the first day of the | |
266 * week, 0 corresponds to Sunday, 1 to Monday, etc. | |
267 */ | |
268 SimileAjax.DateTime.roundDownToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) { | |
269 var timeShift = timeZone * | |
270 SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]; | |
271 | |
272 var date2 = new Date(date.getTime() + timeShift); | |
273 var clearInDay = function(d) { | |
274 d.setUTCMilliseconds(0); | |
275 d.setUTCSeconds(0); | |
276 d.setUTCMinutes(0); | |
277 d.setUTCHours(0); | |
278 }; | |
279 var clearInYear = function(d) { | |
280 clearInDay(d); | |
281 d.setUTCDate(1); | |
282 d.setUTCMonth(0); | |
283 }; | |
284 | |
285 switch(intervalUnit) { | |
286 case SimileAjax.DateTime.MILLISECOND: | |
287 var x = date2.getUTCMilliseconds(); | |
288 date2.setUTCMilliseconds(x - (x % multiple)); | |
289 break; | |
290 case SimileAjax.DateTime.SECOND: | |
291 date2.setUTCMilliseconds(0); | |
292 | |
293 var x = date2.getUTCSeconds(); | |
294 date2.setUTCSeconds(x - (x % multiple)); | |
295 break; | |
296 case SimileAjax.DateTime.MINUTE: | |
297 date2.setUTCMilliseconds(0); | |
298 date2.setUTCSeconds(0); | |
299 | |
300 var x = date2.getUTCMinutes(); | |
301 date2.setTime(date2.getTime() - | |
302 (x % multiple) * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]); | |
303 break; | |
304 case SimileAjax.DateTime.HOUR: | |
305 date2.setUTCMilliseconds(0); | |
306 date2.setUTCSeconds(0); | |
307 date2.setUTCMinutes(0); | |
308 | |
309 var x = date2.getUTCHours(); | |
310 date2.setUTCHours(x - (x % multiple)); | |
311 break; | |
312 case SimileAjax.DateTime.DAY: | |
313 clearInDay(date2); | |
314 break; | |
315 case SimileAjax.DateTime.WEEK: | |
316 clearInDay(date2); | |
317 var d = (date2.getUTCDay() + 7 - firstDayOfWeek) % 7; | |
318 date2.setTime(date2.getTime() - | |
319 d * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]); | |
320 break; | |
321 case SimileAjax.DateTime.MONTH: | |
322 clearInDay(date2); | |
323 date2.setUTCDate(1); | |
324 | |
325 var x = date2.getUTCMonth(); | |
326 date2.setUTCMonth(x - (x % multiple)); | |
327 break; | |
328 case SimileAjax.DateTime.YEAR: | |
329 clearInYear(date2); | |
330 | |
331 var x = date2.getUTCFullYear(); | |
332 date2.setUTCFullYear(x - (x % multiple)); | |
333 break; | |
334 case SimileAjax.DateTime.DECADE: | |
335 clearInYear(date2); | |
336 date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 10) * 10); | |
337 break; | |
338 case SimileAjax.DateTime.CENTURY: | |
339 clearInYear(date2); | |
340 date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 100) * 100); | |
341 break; | |
342 case SimileAjax.DateTime.MILLENNIUM: | |
343 clearInYear(date2); | |
344 date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 1000) * 1000); | |
345 break; | |
346 } | |
347 | |
348 date.setTime(date2.getTime() - timeShift); | |
349 }; | |
350 | |
351 /** | |
352 * Rounds date objects up to the nearest interval or multiple of an interval. | |
353 * This method modifies the given date object, converting it to the given | |
354 * timezone if specified. | |
355 * | |
356 * @param {Date} date the date object to round | |
357 * @param {Number} intervalUnit a constant, integer index specifying an | |
358 * interval, e.g. SimileAjax.DateTime.HOUR | |
359 * @param {Number} timeZone a timezone shift, given in hours | |
360 * @param {Number} multiple a multiple of the interval to round by | |
361 * @param {Number} firstDayOfWeek an integer specifying the first day of the | |
362 * week, 0 corresponds to Sunday, 1 to Monday, etc. | |
363 * @see SimileAjax.DateTime.roundDownToInterval | |
364 */ | |
365 SimileAjax.DateTime.roundUpToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) { | |
366 var originalTime = date.getTime(); | |
367 SimileAjax.DateTime.roundDownToInterval(date, intervalUnit, timeZone, multiple, firstDayOfWeek); | |
368 if (date.getTime() < originalTime) { | |
369 date.setTime(date.getTime() + | |
370 SimileAjax.DateTime.gregorianUnitLengths[intervalUnit] * multiple); | |
371 } | |
372 }; | |
373 | |
374 /** | |
375 * Increments a date object by a specified interval, taking into | |
376 * consideration the timezone. | |
377 * | |
378 * @param {Date} date the date object to increment | |
379 * @param {Number} intervalUnit a constant, integer index specifying an | |
380 * interval, e.g. SimileAjax.DateTime.HOUR | |
381 * @param {Number} timeZone the timezone offset in hours | |
382 */ | |
383 SimileAjax.DateTime.incrementByInterval = function(date, intervalUnit, timeZone) { | |
384 timeZone = (typeof timeZone == 'undefined') ? 0 : timeZone; | |
385 | |
386 var timeShift = timeZone * | |
387 SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]; | |
388 | |
389 var date2 = new Date(date.getTime() + timeShift); | |
390 | |
391 switch(intervalUnit) { | |
392 case SimileAjax.DateTime.MILLISECOND: | |
393 date2.setTime(date2.getTime() + 1) | |
394 break; | |
395 case SimileAjax.DateTime.SECOND: | |
396 date2.setTime(date2.getTime() + 1000); | |
397 break; | |
398 case SimileAjax.DateTime.MINUTE: | |
399 date2.setTime(date2.getTime() + | |
400 SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]); | |
401 break; | |
402 case SimileAjax.DateTime.HOUR: | |
403 date2.setTime(date2.getTime() + | |
404 SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]); | |
405 break; | |
406 case SimileAjax.DateTime.DAY: | |
407 date2.setUTCDate(date2.getUTCDate() + 1); | |
408 break; | |
409 case SimileAjax.DateTime.WEEK: | |
410 date2.setUTCDate(date2.getUTCDate() + 7); | |
411 break; | |
412 case SimileAjax.DateTime.MONTH: | |
413 date2.setUTCMonth(date2.getUTCMonth() + 1); | |
414 break; | |
415 case SimileAjax.DateTime.YEAR: | |
416 date2.setUTCFullYear(date2.getUTCFullYear() + 1); | |
417 break; | |
418 case SimileAjax.DateTime.DECADE: | |
419 date2.setUTCFullYear(date2.getUTCFullYear() + 10); | |
420 break; | |
421 case SimileAjax.DateTime.CENTURY: | |
422 date2.setUTCFullYear(date2.getUTCFullYear() + 100); | |
423 break; | |
424 case SimileAjax.DateTime.MILLENNIUM: | |
425 date2.setUTCFullYear(date2.getUTCFullYear() + 1000); | |
426 break; | |
427 } | |
428 | |
429 date.setTime(date2.getTime() - timeShift); | |
430 }; | |
431 | |
432 /** | |
433 * Returns a new date object with the given time offset removed. | |
434 * | |
435 * @param {Date} date the starting date | |
436 * @param {Number} timeZone a timezone specified in an hour offset to remove | |
437 * @return {Date} a new date object with the offset removed | |
438 */ | |
439 SimileAjax.DateTime.removeTimeZoneOffset = function(date, timeZone) { | |
440 return new Date(date.getTime() + | |
441 timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]); | |
442 }; | |
443 | |
444 /** | |
445 * Returns the timezone of the user's browser. | |
446 * | |
447 * @return {Number} the timezone in the user's locale in hours | |
448 */ | |
449 SimileAjax.DateTime.getTimezone = function() { | |
450 var d = new Date().getTimezoneOffset(); | |
451 return d / -60; | |
452 }; |