2150 |
mathias |
1 |
if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
|
|
2 |
dojo._hasResource["dojo.date.stamp"] = true;
|
|
|
3 |
dojo.provide("dojo.date.stamp");
|
|
|
4 |
|
|
|
5 |
// Methods to convert dates to or from a wire (string) format using well-known conventions
|
|
|
6 |
|
|
|
7 |
dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
|
|
|
8 |
// summary:
|
|
|
9 |
// Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
|
|
|
10 |
//
|
|
|
11 |
// description:
|
|
|
12 |
// Accepts a string formatted according to a profile of ISO8601 as defined by
|
|
|
13 |
// RFC3339 (http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
|
|
|
14 |
// Can also process dates as specified by http://www.w3.org/TR/NOTE-datetime
|
|
|
15 |
// The following combinations are valid:
|
|
|
16 |
// * dates only
|
|
|
17 |
// yyyy
|
|
|
18 |
// yyyy-MM
|
|
|
19 |
// yyyy-MM-dd
|
|
|
20 |
// * times only, with an optional time zone appended
|
|
|
21 |
// THH:mm
|
|
|
22 |
// THH:mm:ss
|
|
|
23 |
// THH:mm:ss.SSS
|
|
|
24 |
// * and "datetimes" which could be any combination of the above
|
|
|
25 |
// timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
|
|
|
26 |
// Assumes the local time zone if not specified. Does not validate. Improperly formatted
|
|
|
27 |
// input may return null. Arguments which are out of bounds will be handled
|
|
|
28 |
// by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
|
|
|
29 |
//
|
|
|
30 |
// formattedString:
|
|
|
31 |
// A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
|
|
|
32 |
//
|
|
|
33 |
// defaultTime:
|
|
|
34 |
// Used for defaults for fields omitted in the formattedString.
|
|
|
35 |
// Uses 1970-01-01T00:00:00.0Z by default.
|
|
|
36 |
|
|
|
37 |
if(!dojo.date.stamp._isoRegExp){
|
|
|
38 |
dojo.date.stamp._isoRegExp =
|
|
|
39 |
//TODO: could be more restrictive and check for 00-59, etc.
|
|
|
40 |
/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
|
|
|
41 |
}
|
|
|
42 |
|
|
|
43 |
var match = dojo.date.stamp._isoRegExp.exec(formattedString);
|
|
|
44 |
var result = null;
|
|
|
45 |
|
|
|
46 |
if(match){
|
|
|
47 |
match.shift();
|
|
|
48 |
match[1] && match[1]--; // Javascript Date months are 0-based
|
|
|
49 |
match[6] && (match[6] *= 1000); // Javascript Date expects fractional seconds as milliseconds
|
|
|
50 |
|
|
|
51 |
if(defaultTime){
|
|
|
52 |
// mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0
|
|
|
53 |
defaultTime = new Date(defaultTime);
|
|
|
54 |
dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
|
|
|
55 |
return defaultTime["get" + prop]();
|
|
|
56 |
}).forEach(function(value, index){
|
|
|
57 |
if(match[index] === undefined){
|
|
|
58 |
match[index] = value;
|
|
|
59 |
}
|
|
|
60 |
});
|
|
|
61 |
}
|
|
|
62 |
result = new Date(match[0]||1970, match[1]||0, match[2]||0, match[3]||0, match[4]||0, match[5]||0, match[6]||0);
|
|
|
63 |
|
|
|
64 |
var offset = 0;
|
|
|
65 |
var zoneSign = match[7] && match[7].charAt(0);
|
|
|
66 |
if(zoneSign != 'Z'){
|
|
|
67 |
offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
|
|
|
68 |
if(zoneSign != '-'){ offset *= -1; }
|
|
|
69 |
}
|
|
|
70 |
if(zoneSign){
|
|
|
71 |
offset -= result.getTimezoneOffset();
|
|
|
72 |
}
|
|
|
73 |
if(offset){
|
|
|
74 |
result.setTime(result.getTime() + offset * 60000);
|
|
|
75 |
}
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
return result; // Date or null
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*Object?*/options){
|
|
|
82 |
// summary:
|
|
|
83 |
// Format a Date object as a string according a subset of the ISO-8601 standard
|
|
|
84 |
//
|
|
|
85 |
// description:
|
|
|
86 |
// When options.selector is omitted, output follows RFC3339 (http://www.ietf.org/rfc/rfc3339.txt)
|
|
|
87 |
// The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
|
|
|
88 |
// Does not check bounds.
|
|
|
89 |
//
|
|
|
90 |
// dateObject:
|
|
|
91 |
// A Date object
|
|
|
92 |
//
|
|
|
93 |
// object {selector: string, zulu: boolean, milliseconds: boolean}
|
|
|
94 |
// selector- "date" or "time" for partial formatting of the Date object.
|
|
|
95 |
// Both date and time will be formatted by default.
|
|
|
96 |
// zulu- if true, UTC/GMT is used for a timezone
|
|
|
97 |
// milliseconds- if true, output milliseconds
|
|
|
98 |
|
|
|
99 |
var _ = function(n){ return (n < 10) ? "0" + n : n; }
|
|
|
100 |
options = options || {};
|
|
|
101 |
var formattedDate = [];
|
|
|
102 |
var getter = options.zulu ? "getUTC" : "get";
|
|
|
103 |
var date = "";
|
|
|
104 |
if(options.selector != "time"){
|
|
|
105 |
date = [dateObject[getter+"FullYear"](), _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
|
|
|
106 |
}
|
|
|
107 |
formattedDate.push(date);
|
|
|
108 |
if(options.selector != "date"){
|
|
|
109 |
var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
|
|
|
110 |
var millis = dateObject[getter+"Milliseconds"]();
|
|
|
111 |
if(options.milliseconds){
|
|
|
112 |
time += "."+ (millis < 100 ? "0" : "") + _(millis);
|
|
|
113 |
}
|
|
|
114 |
if(options.zulu){
|
|
|
115 |
time += "Z";
|
|
|
116 |
}else if(options.selector != "time"){
|
|
|
117 |
var timezoneOffset = dateObject.getTimezoneOffset();
|
|
|
118 |
var absOffset = Math.abs(timezoneOffset);
|
|
|
119 |
time += (timezoneOffset > 0 ? "-" : "+") +
|
|
|
120 |
_(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
|
|
|
121 |
}
|
|
|
122 |
formattedDate.push(time);
|
|
|
123 |
}
|
|
|
124 |
return formattedDate.join('T'); // String
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
}
|