1 | define(["dojo/_base/kernel", "dojo/date", "dojo/date/locale", "dojo/string", "dojo/cldr/supplemental"], |
---|
2 | function(dojo, dojoDate, dojoDateLocale, dojoString, dojoCldrSupplemental){ |
---|
3 | |
---|
4 | var posix = dojo.getObject("date.posix", true, dojox); |
---|
5 | /*===== |
---|
6 | var posix = { |
---|
7 | // TODO: summary |
---|
8 | }; |
---|
9 | =====*/ |
---|
10 | |
---|
11 | posix.strftime = function(/*Date*/dateObject, /*String*/format, /*String?*/locale){ |
---|
12 | // |
---|
13 | // summary: |
---|
14 | // Formats the date object using the specifications of the POSIX strftime function |
---|
15 | // |
---|
16 | // description: |
---|
17 | // see http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html |
---|
18 | |
---|
19 | // zero pad |
---|
20 | var padChar = null; |
---|
21 | var _ = function(s, n){ |
---|
22 | return dojoString.pad(s, n || 2, padChar || "0"); |
---|
23 | }; |
---|
24 | |
---|
25 | var bundle = dojoDateLocale._getGregorianBundle(locale); |
---|
26 | |
---|
27 | var $ = function(property){ |
---|
28 | switch(property){ |
---|
29 | case "a": // abbreviated weekday name according to the current locale |
---|
30 | return dojoDateLocale.getNames('days', 'abbr', 'format', locale)[dateObject.getDay()]; |
---|
31 | |
---|
32 | case "A": // full weekday name according to the current locale |
---|
33 | return dojoDateLocale.getNames('days', 'wide', 'format', locale)[dateObject.getDay()]; |
---|
34 | |
---|
35 | case "b": |
---|
36 | case "h": // abbreviated month name according to the current locale |
---|
37 | return dojoDateLocale.getNames('months', 'abbr', 'format', locale)[dateObject.getMonth()]; |
---|
38 | |
---|
39 | case "B": // full month name according to the current locale |
---|
40 | return dojoDateLocale.getNames('months', 'wide', 'format', locale)[dateObject.getMonth()]; |
---|
41 | |
---|
42 | case "c": // preferred date and time representation for the current |
---|
43 | // locale |
---|
44 | return dojoDateLocale.format(dateObject, {formatLength: 'full', locale: locale}); |
---|
45 | |
---|
46 | case "C": // century number (the year divided by 100 and truncated |
---|
47 | // to an integer, range 00 to 99) |
---|
48 | return _(Math.floor(dateObject.getFullYear()/100)); |
---|
49 | |
---|
50 | case "d": // day of the month as a decimal number (range 01 to 31) |
---|
51 | return _(dateObject.getDate()); |
---|
52 | |
---|
53 | case "D": // same as %m/%d/%y |
---|
54 | return $("m") + "/" + $("d") + "/" + $("y"); |
---|
55 | |
---|
56 | case "e": // day of the month as a decimal number, a single digit is |
---|
57 | // preceded by a space (range ' 1' to '31') |
---|
58 | if(padChar == null){ padChar = " "; } |
---|
59 | return _(dateObject.getDate()); |
---|
60 | |
---|
61 | case "f": // month as a decimal number, a single digit is |
---|
62 | // preceded by a space (range ' 1' to '12') |
---|
63 | if(padChar == null){ padChar = " "; } |
---|
64 | return _(dateObject.getMonth()+1); |
---|
65 | |
---|
66 | case "g": // like %G, but without the century. |
---|
67 | break; |
---|
68 | |
---|
69 | case "G": // The 4-digit year corresponding to the ISO week number |
---|
70 | // (see %V). This has the same format and value as %Y, |
---|
71 | // except that if the ISO week number belongs to the |
---|
72 | // previous or next year, that year is used instead. |
---|
73 | console.warn("unimplemented modifier 'G'"); |
---|
74 | break; |
---|
75 | |
---|
76 | case "F": // same as %Y-%m-%d |
---|
77 | return $("Y") + "-" + $("m") + "-" + $("d"); |
---|
78 | |
---|
79 | case "H": // hour as a decimal number using a 24-hour clock (range |
---|
80 | // 00 to 23) |
---|
81 | return _(dateObject.getHours()); |
---|
82 | |
---|
83 | case "I": // hour as a decimal number using a 12-hour clock (range |
---|
84 | // 01 to 12) |
---|
85 | return _(dateObject.getHours() % 12 || 12); |
---|
86 | |
---|
87 | case "j": // day of the year as a decimal number (range 001 to 366) |
---|
88 | return _(dojoDateLocale._getDayOfYear(dateObject), 3); |
---|
89 | |
---|
90 | case "k": // Hour as a decimal number using a 24-hour clock (range |
---|
91 | // 0 to 23 (space-padded)) |
---|
92 | if(padChar == null){ padChar = " "; } |
---|
93 | return _(dateObject.getHours()); |
---|
94 | |
---|
95 | case "l": // Hour as a decimal number using a 12-hour clock (range |
---|
96 | // 1 to 12 (space-padded)) |
---|
97 | if(padChar == null){ padChar = " "; } |
---|
98 | return _(dateObject.getHours() % 12 || 12); |
---|
99 | |
---|
100 | case "m": // month as a decimal number (range 01 to 12) |
---|
101 | return _(dateObject.getMonth() + 1); |
---|
102 | |
---|
103 | case "M": // minute as a decimal number |
---|
104 | return _(dateObject.getMinutes()); |
---|
105 | |
---|
106 | case "n": |
---|
107 | return "\n"; |
---|
108 | |
---|
109 | case "p": // either `am' or `pm' according to the given time value, |
---|
110 | // or the corresponding strings for the current locale |
---|
111 | return bundle['dayPeriods-format-wide-' + (dateObject.getHours() < 12 ? "am" : "pm")]; |
---|
112 | |
---|
113 | case "r": // time in a.m. and p.m. notation |
---|
114 | return $("I") + ":" + $("M") + ":" + $("S") + " " + $("p"); |
---|
115 | |
---|
116 | case "R": // time in 24 hour notation |
---|
117 | return $("H") + ":" + $("M"); |
---|
118 | |
---|
119 | case "S": // second as a decimal number |
---|
120 | return _(dateObject.getSeconds()); |
---|
121 | |
---|
122 | case "t": |
---|
123 | return "\t"; |
---|
124 | |
---|
125 | case "T": // current time, equal to %H:%M:%S |
---|
126 | return $("H") + ":" + $("M") + ":" + $("S"); |
---|
127 | |
---|
128 | case "u": // weekday as a decimal number [1,7], with 1 representing |
---|
129 | // Monday |
---|
130 | return String(dateObject.getDay() || 7); |
---|
131 | |
---|
132 | case "U": // week number of the current year as a decimal number, |
---|
133 | // starting with the first Sunday as the first day of the |
---|
134 | // first week |
---|
135 | return _(dojoDateLocale._getWeekOfYear(dateObject)); |
---|
136 | |
---|
137 | case "V": // week number of the year (Monday as the first day of the |
---|
138 | // week) as a decimal number [01,53]. If the week containing |
---|
139 | // 1 January has four or more days in the new year, then it |
---|
140 | // is considered week 1. Otherwise, it is the last week of |
---|
141 | // the previous year, and the next week is week 1. |
---|
142 | return _(posix.getIsoWeekOfYear(dateObject)); |
---|
143 | |
---|
144 | case "W": // week number of the current year as a decimal number, |
---|
145 | // starting with the first Monday as the first day of the |
---|
146 | // first week |
---|
147 | return _(dojoDateLocale._getWeekOfYear(dateObject, 1)); |
---|
148 | |
---|
149 | case "w": // day of the week as a decimal, Sunday being 0 |
---|
150 | return String(dateObject.getDay()); |
---|
151 | |
---|
152 | case "x": // preferred date representation for the current locale |
---|
153 | // without the time |
---|
154 | return dojoDateLocale.format(dateObject, {selector:'date', formatLength: 'full', locale:locale}); |
---|
155 | |
---|
156 | case "X": // preferred time representation for the current locale |
---|
157 | // without the date |
---|
158 | return dojoDateLocale.format(dateObject, {selector:'time', formatLength: 'full', locale:locale}); |
---|
159 | |
---|
160 | case "y": // year as a decimal number without a century (range 00 to |
---|
161 | // 99) |
---|
162 | return _(dateObject.getFullYear()%100); |
---|
163 | |
---|
164 | case "Y": // year as a decimal number including the century |
---|
165 | return String(dateObject.getFullYear()); |
---|
166 | |
---|
167 | case "z": // time zone or name or abbreviation |
---|
168 | var timezoneOffset = dateObject.getTimezoneOffset(); |
---|
169 | return (timezoneOffset > 0 ? "-" : "+") + |
---|
170 | _(Math.floor(Math.abs(timezoneOffset)/60)) + ":" + |
---|
171 | _(Math.abs(timezoneOffset)%60); |
---|
172 | |
---|
173 | case "Z": // time zone or name or abbreviation |
---|
174 | return dojoDate.getTimezoneName(dateObject); |
---|
175 | |
---|
176 | case "%": |
---|
177 | return "%"; |
---|
178 | } |
---|
179 | }; |
---|
180 | |
---|
181 | // parse the formatting string and construct the resulting string |
---|
182 | var string = "", |
---|
183 | i = 0, |
---|
184 | index = 0, |
---|
185 | switchCase = null; |
---|
186 | while ((index = format.indexOf("%", i)) != -1){ |
---|
187 | string += format.substring(i, index++); |
---|
188 | |
---|
189 | // inspect modifier flag |
---|
190 | switch (format.charAt(index++)) { |
---|
191 | case "_": // Pad a numeric result string with spaces. |
---|
192 | padChar = " "; break; |
---|
193 | case "-": // Do not pad a numeric result string. |
---|
194 | padChar = ""; break; |
---|
195 | case "0": // Pad a numeric result string with zeros. |
---|
196 | padChar = "0"; break; |
---|
197 | case "^": // Convert characters in result string to uppercase. |
---|
198 | switchCase = "upper"; break; |
---|
199 | case "*": // Convert characters in result string to lowercase |
---|
200 | switchCase = "lower"; break; |
---|
201 | case "#": // Swap the case of the result string. |
---|
202 | switchCase = "swap"; break; |
---|
203 | default: // no modifier flag so decrement the index |
---|
204 | padChar = null; index--; break; |
---|
205 | } |
---|
206 | |
---|
207 | // toggle case if a flag is set |
---|
208 | var property = $(format.charAt(index++)); |
---|
209 | switch (switchCase){ |
---|
210 | case "upper": |
---|
211 | property = property.toUpperCase(); |
---|
212 | break; |
---|
213 | case "lower": |
---|
214 | property = property.toLowerCase(); |
---|
215 | break; |
---|
216 | case "swap": // Upper to lower, and versey-vicea |
---|
217 | var compareString = property.toLowerCase(); |
---|
218 | var swapString = ''; |
---|
219 | var ch = ''; |
---|
220 | for (var j = 0; j < property.length; j++){ |
---|
221 | ch = property.charAt(j); |
---|
222 | swapString += (ch == compareString.charAt(j)) ? |
---|
223 | ch.toUpperCase() : ch.toLowerCase(); |
---|
224 | } |
---|
225 | property = swapString; |
---|
226 | break; |
---|
227 | default: |
---|
228 | break; |
---|
229 | } |
---|
230 | switchCase = null; |
---|
231 | |
---|
232 | string += property; |
---|
233 | i = index; |
---|
234 | } |
---|
235 | string += format.substring(i); |
---|
236 | |
---|
237 | return string; // String |
---|
238 | }; |
---|
239 | |
---|
240 | posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDay){ |
---|
241 | // summary: |
---|
242 | // Return a date object representing the first day of the given |
---|
243 | // date's week. |
---|
244 | if(isNaN(firstDay)){ |
---|
245 | firstDay = dojoCldrSupplemental.getFirstDayOfWeek ? dojoCldrSupplemental.getFirstDayOfWeek() : 0; |
---|
246 | } |
---|
247 | var offset = firstDay; |
---|
248 | if(dateObject.getDay() >= firstDay){ |
---|
249 | offset -= dateObject.getDay(); |
---|
250 | }else{ |
---|
251 | offset -= (7 - dateObject.getDay()); |
---|
252 | } |
---|
253 | var date = new Date(dateObject); |
---|
254 | date.setHours(0, 0, 0, 0); |
---|
255 | return dojoDate.add(date, "day", offset); // Date |
---|
256 | }; |
---|
257 | |
---|
258 | posix.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week){ |
---|
259 | // summary: |
---|
260 | // Set the ISO8601 week number of the given date. |
---|
261 | // The week containing January 4th is the first week of the year. |
---|
262 | // week: |
---|
263 | // can be positive or negative: -1 is the year's last week. |
---|
264 | if(!week){ return dateObject; } |
---|
265 | var currentWeek = posix.getIsoWeekOfYear(dateObject); |
---|
266 | var offset = week - currentWeek; |
---|
267 | if(week < 0){ |
---|
268 | var weeks = posix.getIsoWeeksInYear(dateObject); |
---|
269 | offset = (weeks + week + 1) - currentWeek; |
---|
270 | } |
---|
271 | return dojoDate.add(dateObject, "week", offset); // Date |
---|
272 | }; |
---|
273 | |
---|
274 | posix.getIsoWeekOfYear = function(/*Date*/dateObject){ |
---|
275 | // summary: |
---|
276 | // Get the ISO8601 week number of the given date. |
---|
277 | // The week containing January 4th is the first week of the year. |
---|
278 | // See http://en.wikipedia.org/wiki/ISO_week_date |
---|
279 | var weekStart = posix.getStartOfWeek(dateObject, 1); |
---|
280 | var yearStart = new Date(dateObject.getFullYear(), 0, 4); // January 4th |
---|
281 | yearStart = posix.getStartOfWeek(yearStart, 1); |
---|
282 | var diff = weekStart.getTime() - yearStart.getTime(); |
---|
283 | if(diff < 0){ return posix.getIsoWeeksInYear(weekStart); } // Integer |
---|
284 | return Math.ceil(diff / 604800000) + 1; // Integer |
---|
285 | }; |
---|
286 | |
---|
287 | posix.getIsoWeeksInYear = function(/*Date*/dateObject) { |
---|
288 | // summary: |
---|
289 | // Determine the number of ISO8601 weeks in the year of the given |
---|
290 | // date. Most years have 52 but some have 53. |
---|
291 | // See http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm |
---|
292 | function p(y) { |
---|
293 | return y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400); |
---|
294 | } |
---|
295 | var y = dateObject.getFullYear(); |
---|
296 | return ( p(y) % 7 == 4 || p(y-1) % 7 == 3 ) ? 53 : 52; // Integer |
---|
297 | }; |
---|
298 | |
---|
299 | return posix; |
---|
300 | |
---|
301 | }); |
---|