[483] | 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 | }); |
---|