date-utils.js.html 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: date-utils.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: date-utils.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>/*
  20. © 2011 by Jerry Sievert
  21. Permission is hereby granted, free of charge, to any person obtaining a copy
  22. of this software and associated documentation files (the "Software"), to deal
  23. in the Software without restriction, including without limitation the rights
  24. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  25. copies of the Software, and to permit persons to whom the Software is
  26. furnished to do so, subject to the following conditions:
  27. The above copyright notice and this permission notice shall be included in
  28. all copies or substantial portions of the Software.
  29. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  32. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  33. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  34. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  35. THE SOFTWARE.
  36. */
  37. (function () {
  38. /** @class Date */
  39. // constants
  40. var monthsAbbr = [
  41. 'Jan',
  42. 'Feb',
  43. 'Mar',
  44. 'Apr',
  45. 'May',
  46. 'Jun',
  47. 'Jul',
  48. 'Aug',
  49. 'Sep',
  50. 'Oct',
  51. 'Nov',
  52. 'Dec'
  53. ];
  54. var monthsFull = [
  55. 'January',
  56. 'February',
  57. 'March',
  58. 'April',
  59. 'May',
  60. 'June',
  61. 'July',
  62. 'August',
  63. 'September',
  64. 'October',
  65. 'November',
  66. 'December'
  67. ];
  68. var daysAbbr = [
  69. 'Sun',
  70. 'Mon',
  71. 'Tue',
  72. 'Wed',
  73. 'Thu',
  74. 'Fri',
  75. 'Sat'
  76. ];
  77. var daysFull = [
  78. 'Sunday',
  79. 'Monday',
  80. 'Tuesday',
  81. 'Wednesday',
  82. 'Thursday',
  83. 'Friday',
  84. 'Saturday'
  85. ];
  86. var dayNames = {
  87. 'su': 0,
  88. 'sun': 0,
  89. 'sunday': 0,
  90. 'mo': 1,
  91. 'mon': 1,
  92. 'monday': 1,
  93. 'tu': 2,
  94. 'tue': 2,
  95. 'tuesday': 2,
  96. 'we': 3,
  97. 'wed': 3,
  98. 'wednesday': 3,
  99. 'th': 4,
  100. 'thu': 4,
  101. 'thursday': 4,
  102. 'fr': 5,
  103. 'fri': 5,
  104. 'friday': 5,
  105. 'sa': 6,
  106. 'sat': 6,
  107. 'saturday': 6
  108. };
  109. var monthsAll = monthsFull.concat(monthsAbbr);
  110. var daysAll = [
  111. 'su',
  112. 'sun',
  113. 'sunday',
  114. 'mo',
  115. 'mon',
  116. 'monday',
  117. 'tu',
  118. 'tue',
  119. 'tuesday',
  120. 'we',
  121. 'wed',
  122. 'wednesday',
  123. 'th',
  124. 'thu',
  125. 'thursday',
  126. 'fr',
  127. 'fri',
  128. 'friday',
  129. 'sa',
  130. 'sat',
  131. 'saturday'
  132. ];
  133. var monthNames = {
  134. 'jan': 0,
  135. 'january': 0,
  136. 'feb': 1,
  137. 'february': 1,
  138. 'mar': 2,
  139. 'march': 2,
  140. 'apr': 3,
  141. 'april': 3,
  142. 'may': 4,
  143. 'jun': 5,
  144. 'june': 5,
  145. 'jul': 6,
  146. 'july': 6,
  147. 'aug': 7,
  148. 'august': 7,
  149. 'sep': 8,
  150. 'september': 8,
  151. 'oct': 9,
  152. 'october': 9,
  153. 'nov': 10,
  154. 'november': 10,
  155. 'dec': 11,
  156. 'december': 11
  157. };
  158. var daysInMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
  159. // private helper functions
  160. /** @ignore */
  161. function pad(str, length) {
  162. str = String(str);
  163. while (str.length &lt; length) {
  164. str = '0' + str;
  165. }
  166. return str;
  167. }
  168. var isInteger = function (str) {
  169. if (str.match(/^(\d+)$/)) {
  170. return true;
  171. }
  172. return false;
  173. };
  174. var getInt = function (str, i, minlength, maxlength) {
  175. for (var x = maxlength; x >= minlength; x--) {
  176. var token = str.substring(i, i + x);
  177. if (token.length &lt; minlength) {
  178. return null;
  179. }
  180. if (isInteger(token)) {
  181. return token;
  182. }
  183. }
  184. return null;
  185. };
  186. // static class methods
  187. var origParse = Date.parse;
  188. // ------------------------------------------------------------------
  189. // getDateFromFormat( date_string , format_string )
  190. //
  191. // This function takes a date string and a format string. It matches
  192. // If the date string matches the format string, it returns the
  193. // getTime() of the date. If it does not match, it returns NaN.
  194. // Original Author: Matt Kruse &lt;matt@mattkruse.com>
  195. // WWW: http://www.mattkruse.com/
  196. // Adapted from: http://www.mattkruse.com/javascript/date/source.html
  197. // ------------------------------------------------------------------
  198. var getDateFromFormat = function (val, format) {
  199. val = val + "";
  200. format = format + "";
  201. var iVal = 0;
  202. var iFormat = 0;
  203. var c = "";
  204. var token = "";
  205. var token2 = "";
  206. var x, y;
  207. var now = new Date();
  208. var year = now.getYear();
  209. var month = now.getMonth() + 1;
  210. var date = 1;
  211. var hh = 0;
  212. var mm = 0;
  213. var ss = 0;
  214. var ampm = "";
  215. while (iFormat &lt; format.length) {
  216. // Get next token from format string
  217. c = format.charAt(iFormat);
  218. token = "";
  219. while ((format.charAt(iFormat) === c) &amp;&amp; (iFormat &lt; format.length)) {
  220. token += format.charAt(iFormat++);
  221. }
  222. // Extract contents of value based on format token
  223. if (token === "yyyy" || token === "yy" || token === "y") {
  224. if (token === "yyyy") {
  225. x = 4;
  226. y = 4;
  227. }
  228. if (token === "yy") {
  229. x = 2;
  230. y = 2;
  231. }
  232. if (token === "y") {
  233. x = 2;
  234. y = 4;
  235. }
  236. year = getInt(val, iVal, x, y);
  237. if (year === null) {
  238. return NaN;
  239. }
  240. iVal += year.length;
  241. if (year.length === 2) {
  242. if (year > 70) {
  243. year = 1900 + (year - 0);
  244. } else {
  245. year = 2000 + (year - 0);
  246. }
  247. }
  248. } else if (token === "MMM" || token === "NNN") {
  249. month = 0;
  250. for (var i = 0; i &lt; monthsAll.length; i++) {
  251. var monthName = monthsAll[i];
  252. if (val.substring(iVal, iVal + monthName.length).toLowerCase() === monthName.toLowerCase()) {
  253. if (token === "MMM" || (token === "NNN" &amp;&amp; i > 11)) {
  254. month = i + 1;
  255. if (month > 12) {
  256. month -= 12;
  257. }
  258. iVal += monthName.length;
  259. break;
  260. }
  261. }
  262. }
  263. if ((month &lt; 1) || (month > 12)) {
  264. return NaN;
  265. }
  266. } else if (token === "EE" || token === "E") {
  267. for (var n = 0; n &lt; daysAll.length; n++) {
  268. var dayName = daysAll[n];
  269. if (val.substring(iVal, iVal + dayName.length).toLowerCase() === dayName.toLowerCase()) {
  270. iVal += dayName.length;
  271. break;
  272. }
  273. }
  274. } else if (token === "MM" || token === "M") {
  275. month = getInt(val, iVal, token.length, 2);
  276. if (month === null || (month &lt; 1) || (month > 12)) {
  277. return NaN;
  278. }
  279. iVal += month.length;
  280. } else if (token === "dd" || token === "d") {
  281. date = getInt(val, iVal, token.length, 2);
  282. if (date === null || (date &lt; 1) || (date > 31)) {
  283. return NaN;
  284. }
  285. iVal += date.length;
  286. } else if (token === "hh" || token === "h") {
  287. hh = getInt(val, iVal, token.length, 2);
  288. if (hh === null || (hh &lt; 1) || (hh > 12)) {
  289. return NaN;
  290. }
  291. iVal += hh.length;
  292. } else if (token === "HH" || token === "H") {
  293. hh = getInt(val, iVal, token.length, 2);
  294. if (hh === null || (hh &lt; 0) || (hh > 23)) {
  295. return NaN;
  296. }
  297. iVal += hh.length;
  298. } else if (token === "KK" || token === "K") {
  299. hh = getInt(val, iVal, token.length, 2);
  300. if (hh === null || (hh &lt; 0) || (hh > 11)) {
  301. return NaN;
  302. }
  303. iVal += hh.length;
  304. } else if (token === "kk" || token === "k") {
  305. hh = getInt(val, iVal, token.length, 2);
  306. if (hh === null || (hh &lt; 1) || (hh > 24)) {
  307. return NaN;
  308. }
  309. iVal += hh.length;
  310. hh--;
  311. } else if (token === "mm" || token === "m") {
  312. mm = getInt(val, iVal, token.length, 2);
  313. if (mm === null || (mm &lt; 0) || (mm > 59)) {
  314. return NaN;
  315. }
  316. iVal += mm.length;
  317. } else if (token === "ss" || token === "s") {
  318. ss = getInt(val, iVal, token.length, 2);
  319. if (ss === null || (ss &lt; 0) || (ss > 59)) {
  320. return NaN;
  321. }
  322. iVal += ss.length;
  323. } else if (token === "a") {
  324. if (val.substring(iVal, iVal + 2).toLowerCase() === "am") {
  325. ampm = "AM";
  326. } else if (val.substring(iVal, iVal + 2).toLowerCase() === "pm") {
  327. ampm = "PM";
  328. } else {
  329. return NaN;
  330. }
  331. iVal += 2;
  332. } else {
  333. if (val.substring(iVal, iVal + token.length) !== token) {
  334. return NaN;
  335. } else {
  336. iVal += token.length;
  337. }
  338. }
  339. }
  340. // If there are any trailing characters left in the value, it doesn't match
  341. if (iVal !== val.length) {
  342. return NaN;
  343. }
  344. // Is date valid for month?
  345. if (month === 2) {
  346. // Check for leap year
  347. if (((year % 4 === 0) &amp;&amp; (year % 100 !== 0)) || (year % 400 === 0)) { // leap year
  348. if (date > 29) {
  349. return NaN;
  350. }
  351. } else {
  352. if (date > 28) {
  353. return NaN;
  354. }
  355. }
  356. }
  357. if ((month === 4) || (month === 6) || (month === 9) || (month === 11)) {
  358. if (date > 30) {
  359. return NaN;
  360. }
  361. }
  362. // Correct hours value
  363. if (hh &lt; 12 &amp;&amp; ampm === "PM") {
  364. hh = hh - 0 + 12;
  365. } else if (hh > 11 &amp;&amp; ampm === "AM") {
  366. hh -= 12;
  367. }
  368. var newdate = new Date(year, month - 1, date, hh, mm, ss);
  369. return newdate.getTime();
  370. };
  371. /** @ignore */
  372. Date.parse = function (date, format) {
  373. if (format) {
  374. return getDateFromFormat(date, format);
  375. }
  376. var timestamp = origParse(date), minutesOffset = 0, match;
  377. if (isNaN(timestamp) &amp;&amp; (match = /^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(date))) {
  378. if (match[8] !== 'Z') {
  379. minutesOffset = +match[10] * 60 + (+match[11]);
  380. if (match[9] === '+') {
  381. minutesOffset = 0 - minutesOffset;
  382. }
  383. }
  384. match[7] = match[7] || '000';
  385. timestamp = Date.UTC(+match[1], +match[2] - 1, +match[3], +match[4], +match[5] + minutesOffset, +match[6], +match[7].substr(0, 3));
  386. }
  387. return timestamp;
  388. };
  389. function polyfill(name, func) {
  390. if (Date.prototype[name] === undefined) {
  391. Date.prototype[name] = func;
  392. }
  393. }
  394. /**
  395. Returns new instance of Date object with the date set to today and
  396. the time set to midnight
  397. @static
  398. @returns {Date} Today's Date
  399. @function today
  400. @memberof Date
  401. */
  402. Date.today = function () {
  403. return new Date().clearTime();
  404. };
  405. /**
  406. Returns new instance of Date object with the date set to today and
  407. the time set to midnight in UTC
  408. @static
  409. @returns {Date} Today's Date in UTC
  410. @function UTCtoday
  411. @memberof Date
  412. */
  413. Date.UTCtoday = function () {
  414. return new Date().clearUTCTime();
  415. };
  416. /**
  417. Returns new instance of Date object with the date set to tomorrow and
  418. the time set to midnight
  419. @static
  420. @returns {Date} Tomorrow's Date
  421. @function tomorrow
  422. @memberof Date
  423. */
  424. Date.tomorrow = function () {
  425. return Date.today().add({days: 1});
  426. };
  427. /**
  428. Returns new instance of Date object with the date set to tomorrow and
  429. the time set to midnight in UTC
  430. @static
  431. @returns {Date} Tomorrow's Date in UTC
  432. @function UTCtomorrow
  433. @memberof Date
  434. */
  435. Date.UTCtomorrow = function () {
  436. return Date.UTCtoday().add({days: 1});
  437. };
  438. /**
  439. Returns new instance of Date object with the date set to yesterday and
  440. the time set to midnight
  441. @static
  442. @returns {Date} Yesterday's Date
  443. @function yesterday
  444. @memberof Date
  445. */
  446. Date.yesterday = function () {
  447. return Date.today().add({days: -1});
  448. };
  449. /**
  450. Returns new instance of Date object with the date set to yesterday and
  451. the time set to midnight in UTC
  452. @static
  453. @returns {Date} Yesterday's Date in UTC
  454. @function UTCyesterday
  455. @memberof Date
  456. */
  457. Date.UTCyesterday = function () {
  458. return Date.UTCtoday().add({days: -1});
  459. };
  460. /**
  461. Returns whether the day is valid
  462. @static
  463. @param day {Number} day of the month
  464. @param year {Number} year
  465. @param month {Number} month of the year [0-11]
  466. @returns {Boolean}
  467. @function validateDay
  468. @memberof Date
  469. */
  470. Date.validateDay = function (day, year, month) {
  471. var date = new Date(year, month, day);
  472. return (date.getFullYear() === year &amp;&amp;
  473. date.getMonth() === month &amp;&amp;
  474. date.getDate() === day);
  475. };
  476. /**
  477. Returns whether the year is valid
  478. @static
  479. @param year {Number} year
  480. @returns {Boolean}
  481. @function validateYear
  482. @memberof Date
  483. */
  484. Date.validateYear = function (year) {
  485. return (year >= 0 &amp;&amp; year &lt;= 9999);
  486. };
  487. /**
  488. Returns whether the second is valid
  489. @static
  490. @param second {Number} second
  491. @returns {Boolean}
  492. @function validateSecond
  493. @memberof Date
  494. */
  495. Date.validateSecond = function (second) {
  496. return (second >= 0 &amp;&amp; second &lt; 60);
  497. };
  498. /**
  499. Returns whether the month is valid [0-11]
  500. @static
  501. @param month {Number} month
  502. @returns {Boolean}
  503. @function validateMonth
  504. @memberof Date
  505. */
  506. Date.validateMonth = function (month) {
  507. return (month >= 0 &amp;&amp; month &lt; 12);
  508. };
  509. /**
  510. Returns whether the minute is valid
  511. @static
  512. @param minute {Number} minute
  513. @returns {Boolean}
  514. @function validateMinute
  515. @memberof Date
  516. */
  517. Date.validateMinute = function (minute) {
  518. return (minute >= 0 &amp;&amp; minute &lt; 60);
  519. };
  520. /**
  521. Returns whether the millisecond is valid
  522. @static
  523. @param millisecond {Number} millisecond
  524. @returns {Boolean}
  525. @function validateMillisecond
  526. @memberof Date
  527. */
  528. Date.validateMillisecond = function (milli) {
  529. return (milli >= 0 &amp;&amp; milli &lt; 1000);
  530. };
  531. /**
  532. Returns whether the hour is valid [0-23]
  533. @static
  534. @param hour {Number} hour
  535. @returns {Boolean}
  536. @function validateHour
  537. @memberof Date
  538. */
  539. Date.validateHour = function (hour) {
  540. return (hour >= 0 &amp;&amp; hour &lt; 24);
  541. };
  542. /**
  543. Compares two dates
  544. @static
  545. @param date1 {Date} first date
  546. @param date2 {Date} second date
  547. @returns {Number} -1 if date1 is less than date2, 0 if they are equal, 1 if date1 is more than date2
  548. @function compare
  549. @memberof Date
  550. */
  551. Date.compare = function (date1, date2) {
  552. if (date1.valueOf() &lt; date2.valueOf()) {
  553. return -1;
  554. } else if (date1.valueOf() > date2.valueOf()) {
  555. return 1;
  556. }
  557. return 0;
  558. };
  559. /**
  560. Compares two dates to the millisecond
  561. @static
  562. @param date1 {Date} first date
  563. @param date2 {Date} second date
  564. @returns {Boolean}
  565. @function equals
  566. @memberof Date
  567. */
  568. Date.equals = function (date1, date2) {
  569. return date1.valueOf() === date2.valueOf();
  570. };
  571. /**
  572. Compares two dates by day
  573. @static
  574. @param date1 {Date} first date
  575. @param date2 {Date} second date
  576. @returns {Boolean}
  577. @function equalsDay
  578. @memberof Date
  579. */
  580. Date.equalsDay = function (date1, date2) {
  581. return date1.toYMD() === date2.toYMD();
  582. };
  583. /**
  584. Returns the day number for a day [0-6]
  585. @static
  586. @param day {String} day name
  587. @returns {Number}
  588. @function getDayNumberFromName
  589. @memberof Date
  590. */
  591. Date.getDayNumberFromName = function (name) {
  592. return dayNames[name.toLowerCase()];
  593. };
  594. /**
  595. Returns the day number for a month [0-11]
  596. @static
  597. @param month {String} month name
  598. @returns {Number}
  599. @function getMonthNumberFromName
  600. @memberof Date
  601. */
  602. Date.getMonthNumberFromName = function (name) {
  603. return monthNames[name.toLowerCase()];
  604. };
  605. /**
  606. Returns the month name for a month [0-11]
  607. @static
  608. @param month {Number} month
  609. @returns {String}
  610. @function getMonthNameFromNumber
  611. @memberof Date
  612. */
  613. Date.getMonthNameFromNumber = function (number) {
  614. return monthsFull[number];
  615. };
  616. /**
  617. Returns the month name abbreviated for a month [0-11]
  618. @static
  619. @param month {Number} month
  620. @returns {String}
  621. @function getMonthAbbrNameFromNumber
  622. @memberof Date
  623. */
  624. Date.getMonthAbbrFromNumber = function (number) {
  625. return monthsAbbr[number];
  626. };
  627. /**
  628. Returns whether or not the year is a leap year
  629. @static
  630. @param year {Number} year
  631. @returns {Boolean}
  632. @function isLeapYear
  633. @memberof Date
  634. */
  635. Date.isLeapYear = function (year) {
  636. return (new Date(year, 1, 29).getDate() === 29);
  637. };
  638. /**
  639. Returns the number of days in a month
  640. @static
  641. @param year {Number} year
  642. @param month {Number} month
  643. @returns {String}
  644. @function getDaysInMonth
  645. @memberof Date
  646. */
  647. Date.getDaysInMonth = function (year, month) {
  648. if (month === 1) {
  649. return Date.isLeapYear(year) ? 29 : 28;
  650. }
  651. return daysInMonth[month];
  652. };
  653. polyfill('getMonthAbbr', function () {
  654. return monthsAbbr[this.getMonth()];
  655. });
  656. polyfill('getMonthName', function () {
  657. return monthsFull[this.getMonth()];
  658. });
  659. polyfill('getLastMonthName', function () {
  660. var i = this.getMonth();
  661. i = (i === 0 ? 11 : i - 1);
  662. return monthsFull[i];
  663. });
  664. polyfill('getUTCOffset', function () {
  665. var tz = pad(Math.abs(this.getTimezoneOffset() / 0.6), 4);
  666. if (this.getTimezoneOffset() > 0) {
  667. tz = '-' + tz;
  668. }
  669. return tz;
  670. });
  671. polyfill('toCLFString', function () {
  672. return pad(this.getDate(), 2) + '/' + this.getMonthAbbr() + '/' +
  673. this.getFullYear() + ':' + pad(this.getHours(), 2) + ':' +
  674. pad(this.getMinutes(), 2) + ':' + pad(this.getSeconds(), 2) +
  675. ' ' + this.getUTCOffset();
  676. });
  677. polyfill('toYMD', function (separator) {
  678. separator = typeof separator === 'undefined' ? '-' : separator;
  679. return this.getFullYear() + separator + pad(this.getMonth() + 1, 2) +
  680. separator + pad(this.getDate(), 2);
  681. });
  682. polyfill('toDBString', function () {
  683. return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1, 2) +
  684. '-' + pad(this.getUTCDate(), 2) + ' ' + pad(this.getUTCHours(), 2) +
  685. ':' + pad(this.getUTCMinutes(), 2) + ':' + pad(this.getUTCSeconds(), 2);
  686. });
  687. polyfill('clearTime', function () {
  688. this.setHours(0);
  689. this.setMinutes(0);
  690. this.setSeconds(0);
  691. this.setMilliseconds(0);
  692. return this;
  693. });
  694. polyfill('clearUTCTime', function () {
  695. this.setUTCHours(0);
  696. this.setUTCMinutes(0);
  697. this.setUTCSeconds(0);
  698. this.setUTCMilliseconds(0);
  699. return this;
  700. });
  701. polyfill('add', function (obj) {
  702. if (obj.milliseconds !== undefined) {
  703. this.setMilliseconds(this.getMilliseconds() + obj.milliseconds);
  704. }
  705. if (obj.seconds !== undefined) {
  706. this.setSeconds(this.getSeconds() + obj.seconds);
  707. }
  708. if (obj.minutes !== undefined) {
  709. this.setMinutes(this.getMinutes() + obj.minutes);
  710. }
  711. if (obj.hours !== undefined) {
  712. this.setHours(this.getHours() + obj.hours);
  713. }
  714. if (obj.days !== undefined) {
  715. this.setDate(this.getDate() + obj.days);
  716. }
  717. if (obj.weeks !== undefined) {
  718. this.setDate(this.getDate() + (obj.weeks * 7));
  719. }
  720. if (obj.months !== undefined) {
  721. this.setMonth(this.getMonth() + obj.months);
  722. }
  723. if (obj.years !== undefined) {
  724. this.setFullYear(this.getFullYear() + obj.years);
  725. }
  726. return this;
  727. });
  728. polyfill('addMilliseconds', function (milliseconds) {
  729. return this.add({ milliseconds: milliseconds });
  730. });
  731. polyfill('addSeconds', function (seconds) {
  732. return this.add({ seconds: seconds });
  733. });
  734. polyfill('addMinutes', function (minutes) {
  735. return this.add({ minutes: minutes });
  736. });
  737. polyfill('addHours', function (hours) {
  738. return this.add({ hours: hours });
  739. });
  740. polyfill('addDays', function (days) {
  741. return this.add({ days: days });
  742. });
  743. polyfill('addWeeks', function (weeks) {
  744. return this.add({ days: (weeks * 7) });
  745. });
  746. polyfill('addMonths', function (months) {
  747. return this.add({ months: months });
  748. });
  749. polyfill('addYears', function (years) {
  750. return this.add({ years: years });
  751. });
  752. polyfill('remove', function (obj) {
  753. if (obj.seconds !== undefined) {
  754. this.setSeconds(this.getSeconds() - obj.seconds);
  755. }
  756. if (obj.minutes !== undefined) {
  757. this.setMinutes(this.getMinutes() - obj.minutes);
  758. }
  759. if (obj.hours !== undefined) {
  760. this.setHours(this.getHours() - obj.hours);
  761. }
  762. if (obj.days !== undefined) {
  763. this.setDate(this.getDate() - obj.days);
  764. }
  765. if (obj.weeks !== undefined) {
  766. this.setDate(this.getDate() - (obj.weeks * 7));
  767. }
  768. if (obj.months !== undefined) {
  769. this.setMonth(this.getMonth() - obj.months);
  770. }
  771. if (obj.years !== undefined) {
  772. this.setFullYear(this.getFullYear() - obj.years);
  773. }
  774. return this;
  775. });
  776. polyfill('removeMilliseconds', function (milliseconds) {
  777. throw new Error('Not implemented');
  778. });
  779. polyfill('removeSeconds', function (seconds) {
  780. return this.remove({ seconds: seconds });
  781. });
  782. polyfill('removeMinutes', function (minutes) {
  783. return this.remove({ minutes: minutes });
  784. });
  785. polyfill('removeHours', function (hours) {
  786. return this.remove({ hours: hours });
  787. });
  788. polyfill('removeDays', function (days) {
  789. return this.remove({ days: days });
  790. });
  791. polyfill('removeWeeks', function (weeks) {
  792. return this.remove({ days: (weeks * 7) });
  793. });
  794. polyfill('removeMonths', function (months) {
  795. return this.remove({ months: months });
  796. });
  797. polyfill('removeYears', function (years) {
  798. return this.remove({ years: years });
  799. });
  800. //addWeekdays is based on the Mon-Fri work week schedule
  801. polyfill('addWeekdays', function (weekdays) {
  802. var day = this.getDay();
  803. if (day === 0) { day = 7; }
  804. var daysOffset = weekdays;
  805. var weekspan = Math.floor(( weekdays + day - 1 ) / 5.0);
  806. if (weekdays > 0){
  807. daysOffset += weekspan * 2;
  808. if ( day > 5 ) { daysOffset -= day - 5; }
  809. } else {
  810. daysOffset += Math.min( weekspan * 2, 0);
  811. if ( day > 6 ) { daysOffset -= 1; }
  812. }
  813. return this.addDays( daysOffset );
  814. });
  815. polyfill('setTimeToNow', function () {
  816. var n = new Date();
  817. this.setMilliseconds(n.getMilliseconds());
  818. this.setSeconds(n.getSeconds());
  819. this.setMinutes(n.getMinutes());
  820. this.setHours(n.getHours());
  821. });
  822. polyfill('clone', function () {
  823. return new Date(this.valueOf());
  824. });
  825. polyfill('between', function (start, end) {
  826. return (this.valueOf() >= start.valueOf() &amp;&amp;
  827. this.valueOf() &lt;= end.valueOf());
  828. });
  829. polyfill('compareTo', function (date) {
  830. return Date.compare(this, date);
  831. });
  832. polyfill('equals', function (date) {
  833. return Date.equals(this, date);
  834. });
  835. polyfill('equalsDay', function (date) {
  836. return Date.equalsDay(this, date);
  837. });
  838. polyfill('isToday', function () {
  839. return Date.equalsDay(this, Date.today());
  840. });
  841. polyfill('isAfter', function (date) {
  842. date = date ? date : new Date();
  843. return (this.compareTo(date) > 0);
  844. });
  845. polyfill('isBefore', function (date) {
  846. date = date ? date : new Date();
  847. return (this.compareTo(date) &lt; 0);
  848. });
  849. //isWeekend is based on the Sat, Sun weekend definition.
  850. polyfill('isWeekend', function (date) {
  851. return (this.getDay() % 6 === 0);
  852. });
  853. polyfill('getDaysBetween', function (date) {
  854. return ((date.clone().valueOf() - this.valueOf()) / 86400000) | 0;
  855. });
  856. polyfill('getHoursBetween', function (date) {
  857. return ((date.clone().valueOf() - this.valueOf()) / 3600000) | 0;
  858. });
  859. polyfill('getMinutesBetween', function (date) {
  860. return ((date.clone().valueOf() - this.valueOf()) / 60000) | 0;
  861. });
  862. polyfill('getSecondsBetween', function (date) {
  863. return ((date.clone().valueOf() - this.valueOf()) / 1000) | 0;
  864. });
  865. polyfill('getMillisecondsBetween', function (date) {
  866. return ((date.clone().valueOf() - this.valueOf())) | 0;
  867. });
  868. polyfill('getMonthsBetween', function (date) {
  869. // make a guess at the answer; using 31 means that we'll be close but won't exceed
  870. var daysDiff, daysInMonth,
  871. months = Math.ceil( new Date(date - this).getUTCDate() / 31 ) ,
  872. testDate = new Date( this.getTime() ),
  873. totalDays = Date.getDaysInMonth;
  874. // find the maximum number of months that's less than or equal to the end date
  875. testDate.setUTCMonth( testDate.getUTCMonth() + months );
  876. while ( testDate.getTime() &lt; date.getTime() ) {
  877. testDate.setUTCMonth( testDate.getUTCMonth() + 1 );
  878. months++;
  879. }
  880. if ( testDate.getTime() !== date.getTime() ) {
  881. // back off 1 month since we exceeded the end date
  882. testDate.setUTCMonth( testDate.getUTCMonth() - 1 );
  883. months--;
  884. }
  885. if ( date.getUTCMonth() === testDate.getUTCMonth() ) {
  886. daysDiff = new Date( date - testDate ).getUTCDate();
  887. daysInMonth = totalDays( testDate.getUTCFullYear(), testDate.getUTCMonth() );
  888. return months + ( daysDiff / daysInMonth );
  889. } else {
  890. // if two dates are on different months,
  891. // the calculation must be done for each separate month
  892. // because their number of days can be different
  893. daysInMonth = totalDays( testDate.getUTCFullYear(), testDate.getUTCMonth() );
  894. daysDiff = daysInMonth - testDate.getUTCDate() + 1;
  895. return months +
  896. (+( daysDiff / daysInMonth ).toFixed( 5 )) +
  897. (+( date.getUTCDate() / totalDays( date.getUTCFullYear(), date.getUTCMonth() ) ).toFixed( 5 ));
  898. }
  899. });
  900. polyfill('getOrdinalNumber', function () {
  901. return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
  902. });
  903. polyfill('toFormat', function (format) {
  904. return toFormat(format, getReplaceMap(this));
  905. });
  906. polyfill('toUTCFormat', function (format) {
  907. return toFormat(format, getUTCReplaceMap(this));
  908. });
  909. polyfill('getWeekNumber', function() {
  910. var onejan = new Date(this.getFullYear(),0,1);
  911. return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
  912. });
  913. polyfill('getFullWeekNumber', function() {
  914. var weekNumber = '' + this.getWeekNumber();
  915. if (weekNumber.length === 1) {
  916. weekNumber = "0" + weekNumber;
  917. }
  918. return weekNumber;
  919. });
  920. var toFormat = function(format, replaceMap) {
  921. var f = [ format ], i, l, s;
  922. var replace = function (str, rep) {
  923. var i = 0, l = f.length, j, ll, t, n = [];
  924. for (; i &lt; l; i++) {
  925. if (typeof f[i] == 'string') {
  926. t = f[i].split(str);
  927. for (j = 0, ll = t.length - 1; j &lt; ll; j++) {
  928. n.push(t[j]);
  929. n.push([rep]); // replacement pushed as non-string
  930. }
  931. n.push(t[ll]);
  932. } else {
  933. // must be a replacement, don't process, just push
  934. n.push(f[i]);
  935. }
  936. }
  937. f = n;
  938. };
  939. for (i in replaceMap) {
  940. replace(i, replaceMap[i]);
  941. }
  942. s = '';
  943. for (i = 0, l = f.length; i &lt; l; i++)
  944. s += typeof f[i] == 'string' ? f[i] : f[i][0];
  945. return f.join('');
  946. };
  947. var getReplaceMap = function(date) {
  948. var hours = (date.getHours() % 12) ? date.getHours() % 12 : 12;
  949. return {
  950. 'YYYY': date.getFullYear(),
  951. 'YY': String(date.getFullYear()).slice(-2),
  952. 'MMMM': monthsFull[date.getMonth()],
  953. 'MMM': monthsAbbr[date.getMonth()],
  954. 'MM': pad(date.getMonth() + 1, 2),
  955. 'MI': pad(date.getMinutes(), 2),
  956. 'M': date.getMonth() + 1,
  957. 'DDDD': daysFull[date.getDay()],
  958. 'DDD': daysAbbr[date.getDay()],
  959. 'DD': pad(date.getDate(), 2),
  960. 'D': date.getDate(),
  961. 'HH24': pad(date.getHours(), 2),
  962. 'HH': pad(hours, 2),
  963. 'H': hours,
  964. 'SS': pad(date.getSeconds(), 2),
  965. 'PP': (date.getHours() >= 12) ? 'PM' : 'AM',
  966. 'P': (date.getHours() >= 12) ? 'pm' : 'am',
  967. 'LL': pad(date.getMilliseconds(), 3)
  968. };
  969. };
  970. var getUTCReplaceMap = function(date) {
  971. var hours = (date.getUTCHours() % 12) ? date.getUTCHours() % 12 : 12;
  972. return {
  973. 'YYYY': date.getUTCFullYear(),
  974. 'YY': String(date.getUTCFullYear()).slice(-2),
  975. 'MMMM': monthsFull[date.getUTCMonth()],
  976. 'MMM': monthsAbbr[date.getUTCMonth()],
  977. 'MM': pad(date.getUTCMonth() + 1, 2),
  978. 'MI': pad(date.getUTCMinutes(), 2),
  979. 'M': date.getUTCMonth() + 1,
  980. 'DDDD': daysFull[date.getUTCDay()],
  981. 'DDD': daysAbbr[date.getUTCDay()],
  982. 'DD': pad(date.getUTCDate(), 2),
  983. 'D': date.getUTCDate(),
  984. 'HH24': pad(date.getUTCHours(), 2),
  985. 'HH': pad(hours, 2),
  986. 'H': hours,
  987. 'SS': pad(date.getUTCSeconds(), 2),
  988. 'PP': (date.getUTCHours() >= 12) ? 'PM' : 'AM',
  989. 'P': (date.getUTCHours() >= 12) ? 'pm' : 'am',
  990. 'LL': pad(date.getUTCMilliseconds(), 3)
  991. };
  992. };
  993. }());
  994. </code></pre>
  995. </article>
  996. </section>
  997. </div>
  998. <nav>
  999. <h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="Date.html">Date</a></li></ul>
  1000. </nav>
  1001. <br clear="both">
  1002. <footer>
  1003. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha5</a> on Sun Jul 13 2014 08:52:44 GMT-0700 (PDT)
  1004. </footer>
  1005. <script> prettyPrint(); </script>
  1006. <script src="scripts/linenumber.js"> </script>
  1007. </body>
  1008. </html>