posix.js 10 KB

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