stamp.js 5.4 KB

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