date-utils.js 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851
  1. /*
  2. © 2011 by Jerry Sievert
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. (function () {
  20. /** @class Date */
  21. // constants
  22. var monthsAbbr = [], monthsFull = [], daysAbbr = [], daysFull = [], dayNames = {}, monthsAll, daysAll = [], monthNames = [];
  23. monthsAbbr = [
  24. 'Jan',
  25. 'Feb',
  26. 'Mar',
  27. 'Apr',
  28. 'May',
  29. 'Jun',
  30. 'Jul',
  31. 'Aug',
  32. 'Sep',
  33. 'Oct',
  34. 'Nov',
  35. 'Dec'
  36. ];
  37. monthsFull = [
  38. 'January',
  39. 'February',
  40. 'March',
  41. 'April',
  42. 'May',
  43. 'June',
  44. 'July',
  45. 'August',
  46. 'September',
  47. 'October',
  48. 'November',
  49. 'December'
  50. ];
  51. daysAbbr = [
  52. 'Sun',
  53. 'Mon',
  54. 'Tue',
  55. 'Wed',
  56. 'Thu',
  57. 'Fri',
  58. 'Sat'
  59. ];
  60. daysFull = [
  61. 'Sunday',
  62. 'Monday',
  63. 'Tuesday',
  64. 'Wednesday',
  65. 'Thursday',
  66. 'Friday',
  67. 'Saturday'
  68. ];
  69. dayNames = {
  70. 'su': 0,
  71. 'sun': 0,
  72. 'sunday': 0,
  73. 'mo': 1,
  74. 'mon': 1,
  75. 'monday': 1,
  76. 'tu': 2,
  77. 'tue': 2,
  78. 'tuesday': 2,
  79. 'we': 3,
  80. 'wed': 3,
  81. 'wednesday': 3,
  82. 'th': 4,
  83. 'thu': 4,
  84. 'thursday': 4,
  85. 'fr': 5,
  86. 'fri': 5,
  87. 'friday': 5,
  88. 'sa': 6,
  89. 'sat': 6,
  90. 'saturday': 6
  91. };
  92. monthsAll = monthsFull.concat(monthsAbbr);
  93. daysAll = [
  94. 'su',
  95. 'sun',
  96. 'sunday',
  97. 'mo',
  98. 'mon',
  99. 'monday',
  100. 'tu',
  101. 'tue',
  102. 'tuesday',
  103. 'we',
  104. 'wed',
  105. 'wednesday',
  106. 'th',
  107. 'thu',
  108. 'thursday',
  109. 'fr',
  110. 'fri',
  111. 'friday',
  112. 'sa',
  113. 'sat',
  114. 'saturday'
  115. ];
  116. monthNames = {
  117. 'jan': 0,
  118. 'january': 0,
  119. 'feb': 1,
  120. 'february': 1,
  121. 'mar': 2,
  122. 'march': 2,
  123. 'apr': 3,
  124. 'april': 3,
  125. 'may': 4,
  126. 'jun': 5,
  127. 'june': 5,
  128. 'jul': 6,
  129. 'july': 6,
  130. 'aug': 7,
  131. 'august': 7,
  132. 'sep': 8,
  133. 'september': 8,
  134. 'oct': 9,
  135. 'october': 9,
  136. 'nov': 10,
  137. 'november': 10,
  138. 'dec': 11,
  139. 'december': 11
  140. };
  141. var daysInMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
  142. // private helper functions
  143. /** @ignore */
  144. function pad(str, length) {
  145. str = String(str);
  146. while (str.length < length) {
  147. str = '0' + str;
  148. }
  149. return str;
  150. }
  151. var isInteger = function (str) {
  152. if (str.match(/^(\d+)$/)) {
  153. return true;
  154. }
  155. return false;
  156. };
  157. var getInt = function (str, i, minlength, maxlength) {
  158. for (var x = maxlength; x >= minlength; x--) {
  159. var token = str.substring(i, i + x);
  160. if (token.length < minlength) {
  161. return null;
  162. }
  163. if (isInteger(token)) {
  164. return token;
  165. }
  166. }
  167. return null;
  168. };
  169. // static class methods
  170. var origParse = Date.parse;
  171. // ------------------------------------------------------------------
  172. // getDateFromFormat( date_string , format_string )
  173. //
  174. // This function takes a date string and a format string. It matches
  175. // If the date string matches the format string, it returns the
  176. // getTime() of the date. If it does not match, it returns NaN.
  177. // Original Author: Matt Kruse <matt@mattkruse.com>
  178. // WWW: http://www.mattkruse.com/
  179. // Adapted from: http://www.mattkruse.com/javascript/date/source.html
  180. // ------------------------------------------------------------------
  181. var getDateFromFormat = function (val, format) {
  182. val = val + "";
  183. format = format + "";
  184. var iVal = 0;
  185. var iFormat = 0;
  186. var c = "";
  187. var token = "";
  188. var token2 = "";
  189. var x, y;
  190. var now = new Date();
  191. var year = now.getYear();
  192. var month = now.getMonth() + 1;
  193. var date = 1;
  194. var hh = 0;
  195. var mm = 0;
  196. var ss = 0;
  197. var ampm = "";
  198. while (iFormat < format.length) {
  199. // Get next token from format string
  200. c = format.charAt(iFormat);
  201. token = "";
  202. while ((format.charAt(iFormat) === c) && (iFormat < format.length)) {
  203. token += format.charAt(iFormat++);
  204. }
  205. // Extract contents of value based on format token
  206. if (token === "yyyy" || token === "yy" || token === "y") {
  207. if (token === "yyyy") {
  208. x = 4;
  209. y = 4;
  210. }
  211. if (token === "yy") {
  212. x = 2;
  213. y = 2;
  214. }
  215. if (token === "y") {
  216. x = 2;
  217. y = 4;
  218. }
  219. year = getInt(val, iVal, x, y);
  220. if (year === null) {
  221. return NaN;
  222. }
  223. iVal += year.length;
  224. if (year.length === 2) {
  225. if (year > 70) {
  226. year = 1900 + (year - 0);
  227. } else {
  228. year = 2000 + (year - 0);
  229. }
  230. }
  231. } else if (token === "MMM" || token === "NNN") {
  232. month = 0;
  233. for (var i = 0; i < monthsAll.length; i++) {
  234. var monthName = monthsAll[i];
  235. if (val.substring(iVal, iVal + monthName.length).toLowerCase() === monthName.toLowerCase()) {
  236. if (token === "MMM" || (token === "NNN" && i > 11)) {
  237. month = i + 1;
  238. if (month > 12) {
  239. month -= 12;
  240. }
  241. iVal += monthName.length;
  242. break;
  243. }
  244. }
  245. }
  246. if ((month < 1) || (month > 12)) {
  247. return NaN;
  248. }
  249. } else if (token === "EE" || token === "E") {
  250. for (var n = 0; n < daysAll.length; n++) {
  251. var dayName = daysAll[n];
  252. if (val.substring(iVal, iVal + dayName.length).toLowerCase() === dayName.toLowerCase()) {
  253. iVal += dayName.length;
  254. break;
  255. }
  256. }
  257. } else if (token === "MM" || token === "M") {
  258. month = getInt(val, iVal, token.length, 2);
  259. if (month === null || (month < 1) || (month > 12)) {
  260. return NaN;
  261. }
  262. iVal += month.length;
  263. } else if (token === "dd" || token === "d") {
  264. date = getInt(val, iVal, token.length, 2);
  265. if (date === null || (date < 1) || (date > 31)) {
  266. return NaN;
  267. }
  268. iVal += date.length;
  269. } else if (token === "hh" || token === "h") {
  270. hh = getInt(val, iVal, token.length, 2);
  271. if (hh === null || (hh < 1) || (hh > 12)) {
  272. return NaN;
  273. }
  274. iVal += hh.length;
  275. } else if (token === "HH" || token === "H") {
  276. hh = getInt(val, iVal, token.length, 2);
  277. if (hh === null || (hh < 0) || (hh > 23)) {
  278. return NaN;
  279. }
  280. iVal += hh.length;
  281. } else if (token === "KK" || token === "K") {
  282. hh = getInt(val, iVal, token.length, 2);
  283. if (hh === null || (hh < 0) || (hh > 11)) {
  284. return NaN;
  285. }
  286. iVal += hh.length;
  287. } else if (token === "kk" || token === "k") {
  288. hh = getInt(val, iVal, token.length, 2);
  289. if (hh === null || (hh < 1) || (hh > 24)) {
  290. return NaN;
  291. }
  292. iVal += hh.length;
  293. hh--;
  294. } else if (token === "mm" || token === "m") {
  295. mm = getInt(val, iVal, token.length, 2);
  296. if (mm === null || (mm < 0) || (mm > 59)) {
  297. return NaN;
  298. }
  299. iVal += mm.length;
  300. } else if (token === "ss" || token === "s") {
  301. ss = getInt(val, iVal, token.length, 2);
  302. if (ss === null || (ss < 0) || (ss > 59)) {
  303. return NaN;
  304. }
  305. iVal += ss.length;
  306. } else if (token === "a") {
  307. if (val.substring(iVal, iVal + 2).toLowerCase() === "am") {
  308. ampm = "AM";
  309. } else if (val.substring(iVal, iVal + 2).toLowerCase() === "pm") {
  310. ampm = "PM";
  311. } else {
  312. return NaN;
  313. }
  314. iVal += 2;
  315. } else {
  316. if (val.substring(iVal, iVal + token.length) !== token) {
  317. return NaN;
  318. } else {
  319. iVal += token.length;
  320. }
  321. }
  322. }
  323. // If there are any trailing characters left in the value, it doesn't match
  324. if (iVal !== val.length) {
  325. return NaN;
  326. }
  327. // Is date valid for month?
  328. if (month === 2) {
  329. // Check for leap year
  330. if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) { // leap year
  331. if (date > 29) {
  332. return NaN;
  333. }
  334. } else {
  335. if (date > 28) {
  336. return NaN;
  337. }
  338. }
  339. }
  340. if ((month === 4) || (month === 6) || (month === 9) || (month === 11)) {
  341. if (date > 30) {
  342. return NaN;
  343. }
  344. }
  345. // Correct hours value
  346. if (hh < 12 && ampm === "PM") {
  347. hh = hh - 0 + 12;
  348. } else if (hh > 11 && ampm === "AM") {
  349. hh -= 12;
  350. }
  351. var newdate = new Date(year, month - 1, date, hh, mm, ss);
  352. return newdate.getTime();
  353. };
  354. /** @ignore */
  355. Date.parse = function (date, format) {
  356. if (format) {
  357. return getDateFromFormat(date, format);
  358. }
  359. var timestamp = origParse(date), minutesOffset = 0, match;
  360. if (isNaN(timestamp) && (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))) {
  361. if (match[8] !== 'Z') {
  362. minutesOffset = +match[10] * 60 + (+match[11]);
  363. if (match[9] === '+') {
  364. minutesOffset = 0 - minutesOffset;
  365. }
  366. }
  367. match[7] = match[7] || '000';
  368. timestamp = Date.UTC(+match[1], +match[2] - 1, +match[3], +match[4], +match[5] + minutesOffset, +match[6], +match[7].substr(0, 3));
  369. }
  370. return timestamp;
  371. };
  372. function polyfill(name, func) {
  373. if (Date.prototype[name] === undefined) {
  374. Date.prototype[name] = func;
  375. }
  376. }
  377. /**
  378. Returns new instance of Date object with the date set to today and
  379. the time set to midnight
  380. @static
  381. @returns {Date} Today's Date
  382. @function today
  383. @memberof Date
  384. */
  385. Date.today = function () {
  386. return new Date().clearTime();
  387. };
  388. /**
  389. Returns new instance of Date object with the date set to today and
  390. the time set to midnight in UTC
  391. @static
  392. @returns {Date} Today's Date in UTC
  393. @function UTCtoday
  394. @memberof Date
  395. */
  396. Date.UTCtoday = function () {
  397. return new Date().clearUTCTime();
  398. };
  399. /**
  400. Returns new instance of Date object with the date set to tomorrow and
  401. the time set to midnight
  402. @static
  403. @returns {Date} Tomorrow's Date
  404. @function tomorrow
  405. @memberof Date
  406. */
  407. Date.tomorrow = function () {
  408. return Date.today().add({days: 1});
  409. };
  410. /**
  411. Returns new instance of Date object with the date set to tomorrow and
  412. the time set to midnight in UTC
  413. @static
  414. @returns {Date} Tomorrow's Date in UTC
  415. @function UTCtomorrow
  416. @memberof Date
  417. */
  418. Date.UTCtomorrow = function () {
  419. return Date.UTCtoday().add({days: 1});
  420. };
  421. /**
  422. Returns new instance of Date object with the date set to yesterday and
  423. the time set to midnight
  424. @static
  425. @returns {Date} Yesterday's Date
  426. @function yesterday
  427. @memberof Date
  428. */
  429. Date.yesterday = function () {
  430. return Date.today().add({days: -1});
  431. };
  432. /**
  433. Returns new instance of Date object with the date set to yesterday and
  434. the time set to midnight in UTC
  435. @static
  436. @returns {Date} Yesterday's Date in UTC
  437. @function UTCyesterday
  438. @memberof Date
  439. */
  440. Date.UTCyesterday = function () {
  441. return Date.UTCtoday().add({days: -1});
  442. };
  443. /**
  444. Returns whether the day is valid
  445. @static
  446. @param day {Number} day of the month
  447. @param year {Number} year
  448. @param month {Number} month of the year [0-11]
  449. @returns {Boolean}
  450. @function validateDay
  451. @memberof Date
  452. */
  453. Date.validateDay = function (day, year, month) {
  454. var date = new Date(year, month, day);
  455. return (date.getFullYear() === year &&
  456. date.getMonth() === month &&
  457. date.getDate() === day);
  458. };
  459. /**
  460. Returns whether the year is valid
  461. @static
  462. @param year {Number} year
  463. @returns {Boolean}
  464. @function validateYear
  465. @memberof Date
  466. */
  467. Date.validateYear = function (year) {
  468. return (year >= 0 && year <= 9999);
  469. };
  470. /**
  471. Returns whether the second is valid
  472. @static
  473. @param second {Number} second
  474. @returns {Boolean}
  475. @function validateSecond
  476. @memberof Date
  477. */
  478. Date.validateSecond = function (second) {
  479. return (second >= 0 && second < 60);
  480. };
  481. /**
  482. Returns whether the month is valid [0-11]
  483. @static
  484. @param month {Number} month
  485. @returns {Boolean}
  486. @function validateMonth
  487. @memberof Date
  488. */
  489. Date.validateMonth = function (month) {
  490. return (month >= 0 && month < 12);
  491. };
  492. /**
  493. Returns whether the minute is valid
  494. @static
  495. @param minute {Number} minute
  496. @returns {Boolean}
  497. @function validateMinute
  498. @memberof Date
  499. */
  500. Date.validateMinute = function (minute) {
  501. return (minute >= 0 && minute < 60);
  502. };
  503. /**
  504. Returns whether the millisecond is valid
  505. @static
  506. @param millisecond {Number} millisecond
  507. @returns {Boolean}
  508. @function validateMillisecond
  509. @memberof Date
  510. */
  511. Date.validateMillisecond = function (milli) {
  512. return (milli >= 0 && milli < 1000);
  513. };
  514. /**
  515. Returns whether the hour is valid [0-23]
  516. @static
  517. @param hour {Number} hour
  518. @returns {Boolean}
  519. @function validateHour
  520. @memberof Date
  521. */
  522. Date.validateHour = function (hour) {
  523. return (hour >= 0 && hour < 24);
  524. };
  525. /**
  526. Compares two dates
  527. @static
  528. @param date1 {Date} first date
  529. @param date2 {Date} second date
  530. @returns {Number} -1 if date1 is less than date2, 0 if they are equal, 1 if date1 is more than date2
  531. @function compare
  532. @memberof Date
  533. */
  534. Date.compare = function (date1, date2) {
  535. if (date1.valueOf() < date2.valueOf()) {
  536. return -1;
  537. } else if (date1.valueOf() > date2.valueOf()) {
  538. return 1;
  539. }
  540. return 0;
  541. };
  542. /**
  543. Compares two dates to the millisecond
  544. @static
  545. @param date1 {Date} first date
  546. @param date2 {Date} second date
  547. @returns {Boolean}
  548. @function equals
  549. @memberof Date
  550. */
  551. Date.equals = function (date1, date2) {
  552. return date1.valueOf() === date2.valueOf();
  553. };
  554. /**
  555. Compares two dates by day
  556. @static
  557. @param date1 {Date} first date
  558. @param date2 {Date} second date
  559. @returns {Boolean}
  560. @function equalsDay
  561. @memberof Date
  562. */
  563. Date.equalsDay = function (date1, date2) {
  564. return date1.toYMD() === date2.toYMD();
  565. };
  566. /**
  567. Returns the day number for a day [0-6]
  568. @static
  569. @param day {String} day name
  570. @returns {Number}
  571. @function getDayNumberFromName
  572. @memberof Date
  573. */
  574. Date.getDayNumberFromName = function (name) {
  575. return dayNames[name.toLowerCase()];
  576. };
  577. /**
  578. Returns the day number for a month [0-11]
  579. @static
  580. @param month {String} month name
  581. @returns {Number}
  582. @function getMonthNumberFromName
  583. @memberof Date
  584. */
  585. Date.getMonthNumberFromName = function (name) {
  586. return monthNames[name.toLowerCase()];
  587. };
  588. /**
  589. Returns the month name for a month [0-11]
  590. @static
  591. @param month {Number} month
  592. @returns {String}
  593. @function getMonthNameFromNumber
  594. @memberof Date
  595. */
  596. Date.getMonthNameFromNumber = function (number) {
  597. return monthsFull[number];
  598. };
  599. /**
  600. Returns the month name abbreviated for a month [0-11]
  601. @static
  602. @param month {Number} month
  603. @returns {String}
  604. @function getMonthAbbrFromNumber
  605. @memberof Date
  606. */
  607. Date.getMonthAbbrFromNumber = function (number) {
  608. return monthsAbbr[number];
  609. };
  610. /**
  611. Returns whether or not the year is a leap year
  612. @static
  613. @param year {Number} year
  614. @returns {Boolean}
  615. @function isLeapYear
  616. @memberof Date
  617. */
  618. Date.isLeapYear = function (year) {
  619. return (new Date(year, 1, 29).getDate() === 29);
  620. };
  621. /**
  622. Returns the number of days in a month
  623. @static
  624. @param year {Number} year
  625. @param month {Number} month
  626. @returns {Number}
  627. @function getDaysInMonth
  628. @memberof Date
  629. */
  630. Date.getDaysInMonth = function (year, month) {
  631. if (month === 1) {
  632. return Date.isLeapYear(year) ? 29 : 28;
  633. }
  634. return daysInMonth[month];
  635. };
  636. /**
  637. Returns the abbreviated month name
  638. @returns {String}
  639. @function getMonthAbbr
  640. @instance
  641. @memberof Date
  642. */
  643. polyfill('getMonthAbbr', function () {
  644. return monthsAbbr[this.getMonth()];
  645. });
  646. /**
  647. Returns the month name
  648. @returns {String}
  649. @function getMonthName
  650. @instance
  651. @memberof Date
  652. */
  653. polyfill('getMonthName', function () {
  654. return monthsFull[this.getMonth()];
  655. });
  656. /**
  657. Returns the name of last month
  658. @returns {String}
  659. @function getLastMonthName
  660. @instance
  661. @memberof Date
  662. */
  663. polyfill('getLastMonthName', function () {
  664. var i = this.getMonth();
  665. i = (i === 0 ? 11 : i - 1);
  666. return monthsFull[i];
  667. });
  668. /**
  669. Returns the current UTC office
  670. @returns {String}
  671. @function getUTCOffset
  672. @instance
  673. @memberof Date
  674. */
  675. polyfill('getUTCOffset', function () {
  676. var tz = pad(Math.abs(this.getTimezoneOffset() / 0.6), 4);
  677. if (this.getTimezoneOffset() > 0) {
  678. tz = '-' + tz;
  679. }
  680. return tz;
  681. });
  682. /**
  683. Returns a padded Common Log Format
  684. @returns {String}
  685. @function toCLFString
  686. @deprecated Will be deprecated in version 2.0 in favor of toFormat
  687. @instance
  688. @memberof Date
  689. */
  690. polyfill('toCLFString', function () {
  691. return pad(this.getDate(), 2) + '/' + this.getMonthAbbr() + '/' +
  692. this.getFullYear() + ':' + pad(this.getHours(), 2) + ':' +
  693. pad(this.getMinutes(), 2) + ':' + pad(this.getSeconds(), 2) +
  694. ' ' + this.getUTCOffset();
  695. });
  696. /**
  697. Returns a padded Year/Month/Day
  698. @returns {String}
  699. @param separator {String} optional, defaults to "-"
  700. @function toYMD
  701. @deprecated Will be deprecated in version 2.0 in favor of toFormat
  702. @instance
  703. @memberof Date
  704. */
  705. polyfill('toYMD', function (separator) {
  706. separator = typeof separator === 'undefined' ? '-' : separator;
  707. return this.getFullYear() + separator + pad(this.getMonth() + 1, 2) +
  708. separator + pad(this.getDate(), 2);
  709. });
  710. /**
  711. Returns a formatted String for database insertion
  712. @returns {String}
  713. @function toDBString
  714. @deprecated Will be deprecated in version 2.0 in favor of toFormat
  715. @instance
  716. @memberof Date
  717. */
  718. polyfill('toDBString', function () {
  719. return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1, 2) +
  720. '-' + pad(this.getUTCDate(), 2) + ' ' + pad(this.getUTCHours(), 2) +
  721. ':' + pad(this.getUTCMinutes(), 2) + ':' + pad(this.getUTCSeconds(), 2);
  722. });
  723. /**
  724. Sets the time to 00:00:00.0000 and returns a new Date object
  725. @returns {Date}
  726. @function clearTime
  727. @instance
  728. @memberof Date
  729. */
  730. polyfill('clearTime', function () {
  731. this.setHours(0);
  732. this.setMinutes(0);
  733. this.setSeconds(0);
  734. this.setMilliseconds(0);
  735. return this;
  736. });
  737. /**
  738. Sets the time to 00:00:00.0000 and returns a new Date object with set to UTC
  739. @returns {Date}
  740. @function clearUTCTime
  741. @instance
  742. @memberof Date
  743. */
  744. polyfill('clearUTCTime', function () {
  745. this.setUTCHours(0);
  746. this.setUTCMinutes(0);
  747. this.setUTCSeconds(0);
  748. this.setUTCMilliseconds(0);
  749. return this;
  750. });
  751. /**
  752. Adds `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years` and returns a new Date.
  753. Usage: `data.add({ "seconds": 10, "days": 1 })`
  754. @param additions {Object}
  755. @returns {Date}
  756. @function add
  757. @instance
  758. @memberof Date
  759. */
  760. polyfill('add', function (obj) {
  761. if (obj.milliseconds !== undefined) {
  762. this.setMilliseconds(this.getMilliseconds() + obj.milliseconds);
  763. }
  764. if (obj.seconds !== undefined) {
  765. this.setSeconds(this.getSeconds() + obj.seconds);
  766. }
  767. if (obj.minutes !== undefined) {
  768. this.setMinutes(this.getMinutes() + obj.minutes);
  769. }
  770. if (obj.hours !== undefined) {
  771. this.setHours(this.getHours() + obj.hours);
  772. }
  773. if (obj.days !== undefined) {
  774. this.setDate(this.getDate() + obj.days);
  775. }
  776. if (obj.weeks !== undefined) {
  777. this.setDate(this.getDate() + (obj.weeks * 7));
  778. }
  779. if (obj.months !== undefined) {
  780. this.setMonth(this.getMonth() + obj.months);
  781. }
  782. if (obj.years !== undefined) {
  783. this.setFullYear(this.getFullYear() + obj.years);
  784. }
  785. return this;
  786. });
  787. /**
  788. Adds milliseconds to the Date and returns it
  789. @returns {Date}
  790. @param milliseconds {Number} Number of milliseconds to add
  791. @function addMilliseconds
  792. @deprecated Will be deprecated in version 2.0 in favor of add
  793. @instance
  794. @memberof Date
  795. */
  796. polyfill('addMilliseconds', function (milliseconds) {
  797. return this.add({ milliseconds: milliseconds });
  798. });
  799. /**
  800. Adds seconds to the Date and returns it
  801. @returns {Date}
  802. @param seconds {Number} Number of seconds to add
  803. @function addSeconds
  804. @deprecated Will be deprecated in version 2.0 in favor of add
  805. @instance
  806. @memberof Date
  807. */
  808. polyfill('addSeconds', function (seconds) {
  809. return this.add({ seconds: seconds });
  810. });
  811. /**
  812. Adds minutes to the Date and returns it
  813. @returns {Date}
  814. @param minutes {Number} Number of minutes to add
  815. @function addMinutes
  816. @deprecated Will be deprecated in version 2.0 in favor of add
  817. @instance
  818. @memberof Date
  819. */
  820. polyfill('addMinutes', function (minutes) {
  821. return this.add({ minutes: minutes });
  822. });
  823. /**
  824. Adds hours to the Date and returns it
  825. @returns {Date}
  826. @param hours {Number} Number of hours to add
  827. @function addHours
  828. @deprecated Will be deprecated in version 2.0 in favor of add
  829. @instance
  830. @memberof Date
  831. */
  832. polyfill('addHours', function (hours) {
  833. return this.add({ hours: hours });
  834. });
  835. /**
  836. Adds days to the Date and returns it
  837. @returns {Date}
  838. @param days {Number} Number of days to add
  839. @function addSeconds
  840. @deprecated Will be deprecated in version 2.0 in favor of add
  841. @instance
  842. @memberof Date
  843. */
  844. polyfill('addDays', function (days) {
  845. return this.add({ days: days });
  846. });
  847. /**
  848. Adds weeks to the Date and returns it
  849. @returns {Date}
  850. @param weeks {Number} Number of weeks to add
  851. @function addWeeks
  852. @deprecated Will be deprecated in version 2.0 in favor of add
  853. @instance
  854. @memberof Date
  855. */
  856. polyfill('addWeeks', function (weeks) {
  857. return this.add({ days: (weeks * 7) });
  858. });
  859. /**
  860. Adds months to the Date and returns it
  861. @returns {Date}
  862. @param months {Number} Number of months to add
  863. @function addMonths
  864. @deprecated Will be deprecated in version 2.0 in favor of add
  865. @instance
  866. @memberof Date
  867. */
  868. polyfill('addMonths', function (months) {
  869. return this.add({ months: months });
  870. });
  871. /**
  872. Adds years to the Date and returns it
  873. @returns {Date}
  874. @param years {Number} Number of years to add
  875. @function addYears
  876. @deprecated Will be deprecated in version 2.0 in favor of add
  877. @instance
  878. @memberof Date
  879. */
  880. polyfill('addYears', function (years) {
  881. return this.add({ years: years });
  882. });
  883. /**
  884. Removes `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years` and returns a new Date.
  885. Usage: `data.remove({ "seconds": 10, "days": 1 })`
  886. @param removals {Object}
  887. @returns {Date}
  888. @function remove
  889. @instance
  890. @memberof Date
  891. */
  892. polyfill('remove', function (obj) {
  893. if (obj.seconds !== undefined) {
  894. this.setSeconds(this.getSeconds() - obj.seconds);
  895. }
  896. if (obj.minutes !== undefined) {
  897. this.setMinutes(this.getMinutes() - obj.minutes);
  898. }
  899. if (obj.hours !== undefined) {
  900. this.setHours(this.getHours() - obj.hours);
  901. }
  902. if (obj.days !== undefined) {
  903. this.setDate(this.getDate() - obj.days);
  904. }
  905. if (obj.weeks !== undefined) {
  906. this.setDate(this.getDate() - (obj.weeks * 7));
  907. }
  908. if (obj.months !== undefined) {
  909. this.setMonth(this.getMonth() - obj.months);
  910. }
  911. if (obj.years !== undefined) {
  912. this.setFullYear(this.getFullYear() - obj.years);
  913. }
  914. return this;
  915. });
  916. /**
  917. Removes milliseconds from the Date and returns it
  918. @returns {Date}
  919. @param milliseconds {Number} Number of millseconds to remove
  920. @function removeMilliseconds
  921. @deprecated Will be deprecated in version 2.0 in favor of remove
  922. @instance
  923. @memberof Date
  924. */
  925. polyfill('removeMilliseconds', function (milliseconds) {
  926. throw new Error('Not implemented');
  927. });
  928. /**
  929. Removes seconds from the Date and returns it
  930. @returns {Date}
  931. @param seconds {Number} Number of seconds to remove
  932. @function removeSeconds
  933. @deprecated Will be deprecated in version 2.0 in favor of remove
  934. @instance
  935. @memberof Date
  936. */
  937. polyfill('removeSeconds', function (seconds) {
  938. return this.remove({ seconds: seconds });
  939. });
  940. /**
  941. Removes minutes from the Date and returns it
  942. @returns {Date}
  943. @param seconds {Number} Number of minutes to remove
  944. @function removeMinutes
  945. @deprecated Will be deprecated in version 2.0 in favor of remove
  946. @instance
  947. @memberof Date
  948. */
  949. polyfill('removeMinutes', function (minutes) {
  950. return this.remove({ minutes: minutes });
  951. });
  952. /**
  953. Removes hours from the Date and returns it
  954. @returns {Date}
  955. @param hours {Number} Number of hours to remove
  956. @function removeHours
  957. @deprecated Will be deprecated in version 2.0 in favor of remove
  958. @instance
  959. @memberof Date
  960. */
  961. polyfill('removeHours', function (hours) {
  962. return this.remove({ hours: hours });
  963. });
  964. /**
  965. Removes days from the Date and returns it
  966. @returns {Date}
  967. @param days {Number} Number of days to remove
  968. @function removeDays
  969. @deprecated Will be deprecated in version 2.0 in favor of remove
  970. @instance
  971. @memberof Date
  972. */
  973. polyfill('removeDays', function (days) {
  974. return this.remove({ days: days });
  975. });
  976. /**
  977. Removes weeks from the Date and returns it
  978. @returns {Date}
  979. @param weeks {Number} Number of weeks to remove
  980. @function removeWeeks
  981. @deprecated Will be deprecated in version 2.0 in favor of remove
  982. @instance
  983. @memberof Date
  984. */
  985. polyfill('removeWeeks', function (weeks) {
  986. return this.remove({ days: (weeks * 7) });
  987. });
  988. /**
  989. Removes months from the Date and returns it
  990. @returns {Date}
  991. @param months {Number} Number of months to remove
  992. @function removeMonths
  993. @deprecated Will be deprecated in version 2.0 in favor of remove
  994. @instance
  995. @memberof Date
  996. */
  997. polyfill('removeMonths', function (months) {
  998. return this.remove({ months: months });
  999. });
  1000. /**
  1001. Removes years from the Date and returns it
  1002. @returns {Date}
  1003. @param years {Number} Number of years to remove
  1004. @function removeYears
  1005. @deprecated Will be deprecated in version 2.0 in favor of remove
  1006. @instance
  1007. @memberof Date
  1008. */
  1009. polyfill('removeYears', function (years) {
  1010. return this.remove({ years: years });
  1011. });
  1012. /**
  1013. Adds weekdays based on a Mon-Fri work schedule and returns it
  1014. @returns {Date}
  1015. @param weekdays {Number} Number of weekdays to add
  1016. @function addWeekdays
  1017. @instance
  1018. @memberof Date
  1019. */
  1020. polyfill('addWeekdays', function (weekdays) {
  1021. var day = this.getDay();
  1022. if (day === 0) { day = 7; }
  1023. var daysOffset = weekdays;
  1024. var weekspan = Math.floor(( weekdays + day - 1 ) / 5.0);
  1025. if (weekdays > 0){
  1026. daysOffset += weekspan * 2;
  1027. if ( day > 5 ) { daysOffset -= day - 5; }
  1028. } else {
  1029. daysOffset += Math.min( weekspan * 2, 0);
  1030. if ( day > 6 ) { daysOffset -= 1; }
  1031. }
  1032. return this.addDays( daysOffset );
  1033. });
  1034. /**
  1035. Sets the time and date to now
  1036. @function setTimeToNow
  1037. @instance
  1038. @memberof Date
  1039. */
  1040. polyfill('setTimeToNow', function () {
  1041. var n = new Date();
  1042. this.setMilliseconds(n.getMilliseconds());
  1043. this.setSeconds(n.getSeconds());
  1044. this.setMinutes(n.getMinutes());
  1045. this.setHours(n.getHours());
  1046. });
  1047. /**
  1048. Returns a cloned copy of the current Date
  1049. @function clone
  1050. @instance
  1051. @memberof Date
  1052. */
  1053. polyfill('clone', function () {
  1054. return new Date(this.valueOf());
  1055. });
  1056. /**
  1057. Returns whether this Date is between a start and end date
  1058. @function between
  1059. @returns {Boolean}
  1060. @instance
  1061. @memberof Date
  1062. */
  1063. polyfill('between', function (start, end) {
  1064. return (this.valueOf() >= start.valueOf() &&
  1065. this.valueOf() <= end.valueOf());
  1066. });
  1067. /**
  1068. Compares a Date to this Date
  1069. @param {Date} Date to compare to
  1070. @function compareTo
  1071. @returns {Number} -1 if less than date, 0 if they are equal, 1 if more than date
  1072. @instance
  1073. @memberof Date
  1074. */
  1075. polyfill('compareTo', function (date) {
  1076. return Date.compare(this, date);
  1077. });
  1078. /**
  1079. Compares a Date and time to this Date and time for equality
  1080. @param {Date} Date to compare to
  1081. @function equals
  1082. @returns {Boolean}
  1083. @instance
  1084. @memberof Date
  1085. */
  1086. polyfill('equals', function (date) {
  1087. return Date.equals(this, date);
  1088. });
  1089. /**
  1090. Compares a Date to this Date for equality
  1091. @param {Date} Date to compare to
  1092. @function equalsDay
  1093. @returns {Boolean}
  1094. @instance
  1095. @memberof Date
  1096. */
  1097. polyfill('equalsDay', function (date) {
  1098. return Date.equalsDay(this, date);
  1099. });
  1100. /**
  1101. Checks to see if the Date is today
  1102. @function isToday
  1103. @returns {Boolean}
  1104. @instance
  1105. @memberof Date
  1106. */
  1107. polyfill('isToday', function () {
  1108. return Date.equalsDay(this, Date.today());
  1109. });
  1110. /**
  1111. Compares a Date to this Date for to see if it is after the Date passed
  1112. @param {Date} Date to compare to
  1113. @function isAfter
  1114. @returns {Boolean}
  1115. @instance
  1116. @memberof Date
  1117. */
  1118. polyfill('isAfter', function (date) {
  1119. date = date ? date : new Date();
  1120. return (this.compareTo(date) > 0);
  1121. });
  1122. /**
  1123. Compares a Date to this Date for to see if it is before the Date passed
  1124. @param {Date} Date to compare to
  1125. @function isBefore
  1126. @returns {Boolean}
  1127. @instance
  1128. @memberof Date
  1129. */
  1130. polyfill('isBefore', function (date) {
  1131. date = date ? date : new Date();
  1132. return (this.compareTo(date) < 0);
  1133. });
  1134. /**
  1135. Returns `true` if the Date is a weekend using standard Saturday/Sunday definition of a weekend
  1136. @function isWeekend
  1137. @returns {Boolean}
  1138. @instance
  1139. @memberof Date
  1140. */
  1141. polyfill('isWeekend', function (date) {
  1142. return (this.getDay() % 6 === 0);
  1143. });
  1144. /**
  1145. Returns the number of days between this Date and the Date passed in
  1146. @function getDaysBetween
  1147. @param {Date} Date to compare to
  1148. @returns {Number}
  1149. @instance
  1150. @memberof Date
  1151. */
  1152. polyfill('getDaysBetween', function (date) {
  1153. return ((date.clone().valueOf() - this.valueOf()) / 86400000) | 0;
  1154. });
  1155. /**
  1156. Returns the number of hours between this Date and the Date passed in
  1157. @function getHoursBetween
  1158. @param {Date} Date to compare to
  1159. @returns {Number}
  1160. @instance
  1161. @memberof Date
  1162. */
  1163. polyfill('getHoursBetween', function (date) {
  1164. return ((date.clone().valueOf() - this.valueOf()) / 3600000) | 0;
  1165. });
  1166. /**
  1167. Returns the number of minutes between this Date and the Date passed in
  1168. @function getMinutesBetween
  1169. @param {Date} Date to compare to
  1170. @returns {Number}
  1171. @instance
  1172. @memberof Date
  1173. */
  1174. polyfill('getMinutesBetween', function (date) {
  1175. return ((date.clone().valueOf() - this.valueOf()) / 60000) | 0;
  1176. });
  1177. /**
  1178. Returns the number of seconds between this Date and the Date passed in
  1179. @function getSecondsBetween
  1180. @param {Date} Date to compare to
  1181. @returns {Number}
  1182. @instance
  1183. @memberof Date
  1184. */
  1185. polyfill('getSecondsBetween', function (date) {
  1186. return ((date.clone().valueOf() - this.valueOf()) / 1000) | 0;
  1187. });
  1188. /**
  1189. Returns the number of milliseconds between this Date and the Date passed in
  1190. @function getMillisecondsBetween
  1191. @param {Date} Date to compare to
  1192. @returns {Number}
  1193. @instance
  1194. @memberof Date
  1195. */
  1196. polyfill('getMillisecondsBetween', function (date) {
  1197. return ((date.clone().valueOf() - this.valueOf())) | 0;
  1198. });
  1199. /**
  1200. Returns the number of months between this Date and the Date passed in
  1201. @function getMonthsBetween
  1202. @param {Date} Date to compare to
  1203. @returns {Number}
  1204. @instance
  1205. @memberof Date
  1206. */
  1207. polyfill('getMonthsBetween', function (date) {
  1208. var daysDiff = Math.abs(((+this) / (86400 * 1000)) - ((+date) / (86400 * 1000)));
  1209. var start = new Date((+date) < (+this) ? (+date) : (+this));
  1210. var end = new Date((date) > (+this) ? (+date) : (+this));
  1211. var months = 0;
  1212. while (+start < +end) {
  1213. months++;
  1214. start = start.addMonths(1);
  1215. }
  1216. var days = Math.abs(((+start) / (86400 * 1000)) - ((+end) / (86400 * 1000)));
  1217. return months - (days / 31);
  1218. });
  1219. /**
  1220. Returns the ordinal number of this Date
  1221. @function getOrdinalNumber
  1222. @returns {Number}
  1223. @instance
  1224. @memberof Date
  1225. */
  1226. polyfill('getOrdinalNumber', function () {
  1227. return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
  1228. });
  1229. /**
  1230. Returns the a formatted version of this Date
  1231. @function toFormat
  1232. @param format {String} Format of the Date, using `YYYY`, `YY`, `MM`, `DD`, `HH`, `HH24`, `MI`, `SS`, etc
  1233. @returns {String}
  1234. @instance
  1235. @memberof Date
  1236. */
  1237. polyfill('toFormat', function (format) {
  1238. return toFormat(format, getReplaceMap(this));
  1239. });
  1240. /**
  1241. Returns the a formatted version of the UTC version of this Date
  1242. @function toUTCFormat
  1243. @param format {String} Format of the Date, using `YYYY`, `YY`, `MM`, `DD`, `HH`, `HH24`, `MI`, `SS`, etc
  1244. @returns {String}
  1245. @instance
  1246. @memberof Date
  1247. */
  1248. polyfill('toUTCFormat', function (format) {
  1249. return toFormat(format, getUTCReplaceMap(this));
  1250. });
  1251. /**
  1252. Returns the week number of this Date
  1253. @function getWeekNumber
  1254. @returns {Number}
  1255. @instance
  1256. @memberof Date
  1257. */
  1258. polyfill('getWeekNumber', function() {
  1259. var onejan = new Date(this.getFullYear(),0,1);
  1260. return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
  1261. });
  1262. /**
  1263. Returns the week number of this Date, zero padded
  1264. @function getFullWeekNumber
  1265. @returns {Number}
  1266. @instance
  1267. @memberof Date
  1268. */
  1269. polyfill('getFullWeekNumber', function() {
  1270. var weekNumber = '' + this.getWeekNumber();
  1271. if (weekNumber.length === 1) {
  1272. weekNumber = "0" + weekNumber;
  1273. }
  1274. return weekNumber;
  1275. });
  1276. var toFormat = function(format, replaceMap) {
  1277. var f = [ format ], i, l, s;
  1278. var replace = function (str, rep) {
  1279. var i = 0, l = f.length, j, ll, t, n = [];
  1280. for (; i < l; i++) {
  1281. if (typeof f[i] == 'string') {
  1282. t = f[i].split(str);
  1283. for (j = 0, ll = t.length - 1; j < ll; j++) {
  1284. n.push(t[j]);
  1285. n.push([rep]); // replacement pushed as non-string
  1286. }
  1287. n.push(t[ll]);
  1288. } else {
  1289. // must be a replacement, don't process, just push
  1290. n.push(f[i]);
  1291. }
  1292. }
  1293. f = n;
  1294. };
  1295. for (i in replaceMap) {
  1296. replace(i, replaceMap[i]);
  1297. }
  1298. s = '';
  1299. for (i = 0, l = f.length; i < l; i++)
  1300. s += typeof f[i] == 'string' ? f[i] : f[i][0];
  1301. return f.join('');
  1302. };
  1303. var getReplaceMap = function(date) {
  1304. var hours = (date.getHours() % 12) ? date.getHours() % 12 : 12;
  1305. return {
  1306. 'YYYY': date.getFullYear(),
  1307. 'YY': String(date.getFullYear()).slice(-2),
  1308. 'MMMM': monthsFull[date.getMonth()],
  1309. 'MMM': monthsAbbr[date.getMonth()],
  1310. 'MM': pad(date.getMonth() + 1, 2),
  1311. 'MI': pad(date.getMinutes(), 2),
  1312. 'M': date.getMonth() + 1,
  1313. 'DDDD': daysFull[date.getDay()],
  1314. 'DDD': daysAbbr[date.getDay()],
  1315. 'DD': pad(date.getDate(), 2),
  1316. 'D': date.getDate(),
  1317. 'HH24': pad(date.getHours(), 2),
  1318. 'HH': pad(hours, 2),
  1319. 'H': hours,
  1320. 'SS': pad(date.getSeconds(), 2),
  1321. 'PP': (date.getHours() >= 12) ? 'PM' : 'AM',
  1322. 'P': (date.getHours() >= 12) ? 'pm' : 'am',
  1323. 'LL': pad(date.getMilliseconds(), 3)
  1324. };
  1325. };
  1326. var getUTCReplaceMap = function(date) {
  1327. var hours = (date.getUTCHours() % 12) ? date.getUTCHours() % 12 : 12;
  1328. return {
  1329. 'YYYY': date.getUTCFullYear(),
  1330. 'YY': String(date.getUTCFullYear()).slice(-2),
  1331. 'MMMM': monthsFull[date.getUTCMonth()],
  1332. 'MMM': monthsAbbr[date.getUTCMonth()],
  1333. 'MM': pad(date.getUTCMonth() + 1, 2),
  1334. 'MI': pad(date.getUTCMinutes(), 2),
  1335. 'M': date.getUTCMonth() + 1,
  1336. 'DDDD': daysFull[date.getUTCDay()],
  1337. 'DDD': daysAbbr[date.getUTCDay()],
  1338. 'DD': pad(date.getUTCDate(), 2),
  1339. 'D': date.getUTCDate(),
  1340. 'HH24': pad(date.getUTCHours(), 2),
  1341. 'HH': pad(hours, 2),
  1342. 'H': hours,
  1343. 'SS': pad(date.getUTCSeconds(), 2),
  1344. 'PP': (date.getUTCHours() >= 12) ? 'PM' : 'AM',
  1345. 'P': (date.getUTCHours() >= 12) ? 'pm' : 'am',
  1346. 'LL': pad(date.getUTCMilliseconds(), 3)
  1347. };
  1348. };
  1349. /*
  1350. * change the language
  1351. * @param lang => support "es" Spanish, "fr" french, "pt-BR" Portuguese Brazil
  1352. * translate => diego
  1353. */
  1354. var language = function (lang) {
  1355. if (lang == "es") {
  1356. monthsAbbr = [
  1357. 'Ene',
  1358. 'Feb',
  1359. 'Mar',
  1360. 'Abr',
  1361. 'May',
  1362. 'Jun',
  1363. 'Jul',
  1364. 'Ago',
  1365. 'Sep',
  1366. 'Oct',
  1367. 'Nov',
  1368. 'Dic'
  1369. ];
  1370. monthsFull = [
  1371. 'Enero',
  1372. 'Febrero',
  1373. 'Marzo',
  1374. 'Abril',
  1375. 'Mayo',
  1376. 'Junio',
  1377. 'Julio',
  1378. 'Agosto',
  1379. 'Septiembre',
  1380. 'Octubre',
  1381. 'Noviembre',
  1382. 'Diciembre'
  1383. ];
  1384. daysAbbr = [
  1385. 'Dom',
  1386. 'Lun',
  1387. 'Mar',
  1388. 'Mie',
  1389. 'Jue',
  1390. 'Vie',
  1391. 'Sab'
  1392. ];
  1393. daysFull = [
  1394. 'Domingo',
  1395. 'Lunes',
  1396. 'Martes',
  1397. 'Miércoles',
  1398. 'Jueves',
  1399. 'Viernes',
  1400. 'Sábado'
  1401. ];
  1402. dayNames = {
  1403. 'do': 0,
  1404. 'dom': 0,
  1405. 'domingo': 0,
  1406. 'lu': 1,
  1407. 'lun': 1,
  1408. 'lunes': 1,
  1409. 'ma': 2,
  1410. 'mar': 2,
  1411. 'martes': 2,
  1412. 'mi': 3,
  1413. 'mie': 3,
  1414. 'miercoles': 3,
  1415. 'ju': 4,
  1416. 'jue': 4,
  1417. 'jueves': 4,
  1418. 'vi': 5,
  1419. 'vie': 5,
  1420. 'viernes': 5,
  1421. 'sa': 6,
  1422. 'sab': 6,
  1423. 'sabado': 6
  1424. };
  1425. monthsAll = monthsFull.concat(monthsAbbr);
  1426. daysAll = [
  1427. 'do',
  1428. 'dom',
  1429. 'domingo',
  1430. 'lu',
  1431. 'lun',
  1432. 'lunes',
  1433. 'ma',
  1434. 'mar',
  1435. 'martes',
  1436. 'mi',
  1437. 'mie',
  1438. 'miércoles',
  1439. 'ju',
  1440. 'jue',
  1441. 'jueves',
  1442. 'vi',
  1443. 'vie',
  1444. 'viernes',
  1445. 'sa',
  1446. 'sab',
  1447. 'sábado'
  1448. ];
  1449. monthNames = {
  1450. 'ene': 0,
  1451. 'enero': 0,
  1452. 'feb': 1,
  1453. 'febrero': 1,
  1454. 'mar': 2,
  1455. 'marzo': 2,
  1456. 'abr': 3,
  1457. 'abril': 3,
  1458. 'may': 4,
  1459. 'mayo':4,
  1460. 'jun': 5,
  1461. 'junio': 5,
  1462. 'jul': 6,
  1463. 'julio': 6,
  1464. 'ago': 7,
  1465. 'agosto': 7,
  1466. 'sep': 8,
  1467. 'septiembre': 8,
  1468. 'oct': 9,
  1469. 'octubre': 9,
  1470. 'nov': 10,
  1471. 'noviembre': 10,
  1472. 'dic': 11,
  1473. 'diciembre': 11
  1474. };
  1475. } else if (lang == "fr") {
  1476. monthsAbbr = [
  1477. 'Jan',
  1478. 'Fév',
  1479. 'Mar',
  1480. 'Avr',
  1481. 'Mai',
  1482. 'Jui',
  1483. 'Jul',
  1484. 'Aoû',
  1485. 'Sep',
  1486. 'Oct',
  1487. 'Nov',
  1488. 'Déc'
  1489. ];
  1490. monthsFull = [
  1491. 'Janvier',
  1492. 'Février',
  1493. 'Mars',
  1494. 'Avril',
  1495. 'Mai',
  1496. 'Juin',
  1497. 'Juillet',
  1498. 'Août',
  1499. 'Septembre',
  1500. 'Octobre',
  1501. 'Novembre',
  1502. 'Décembre'
  1503. ];
  1504. daysAbbr = [
  1505. 'Dim',
  1506. 'Lun',
  1507. 'Mar',
  1508. 'Mer',
  1509. 'Jeu',
  1510. 'Ven',
  1511. 'Sam'
  1512. ];
  1513. daysFull = [
  1514. 'Dimanchi',
  1515. 'Lundi',
  1516. 'Mardi',
  1517. 'Mercredi',
  1518. 'Jeudi',
  1519. 'Vendredi',
  1520. 'Samedi'
  1521. ];
  1522. dayNames = {
  1523. 'di': 0,
  1524. 'dim': 0,
  1525. 'dimanchi': 0,
  1526. 'lu': 1,
  1527. 'lun': 1,
  1528. 'lundi': 1,
  1529. 'ma': 2,
  1530. 'mar': 2,
  1531. 'mardi': 2,
  1532. 'me': 3,
  1533. 'mer': 3,
  1534. 'mercredi': 3,
  1535. 'je': 4,
  1536. 'jeu': 4,
  1537. 'jeudi': 4,
  1538. 've': 5,
  1539. 'ven': 5,
  1540. 'vendredi': 5,
  1541. 'sa': 6,
  1542. 'sam': 6,
  1543. 'samedi': 6
  1544. };
  1545. monthsAll = monthsFull.concat(monthsAbbr);
  1546. daysAll = [
  1547. 'di',
  1548. 'dim',
  1549. 'dimanchi',
  1550. 'lu',
  1551. 'lun',
  1552. 'lundi',
  1553. 'ma',
  1554. 'mar',
  1555. 'mardi',
  1556. 'me',
  1557. 'mer',
  1558. 'mercredi',
  1559. 'je',
  1560. 'jeu',
  1561. 'jeudi',
  1562. 've',
  1563. 'ven',
  1564. 'vendredi',
  1565. 'sa',
  1566. 'sam',
  1567. 'samedi'
  1568. ];
  1569. monthNames = {
  1570. 'jan': 0,
  1571. 'janvier': 0,
  1572. 'fév': 1,
  1573. 'février': 1,
  1574. 'mar': 2,
  1575. 'mars': 2,
  1576. 'avr': 3,
  1577. 'avril': 3,
  1578. 'mai': 4,
  1579. 'jui': 5,
  1580. 'juin': 5,
  1581. 'jul': 6,
  1582. 'juillet': 6,
  1583. 'aoû': 7,
  1584. 'août': 7,
  1585. 'sep': 8,
  1586. 'septembre': 8,
  1587. 'oct': 9,
  1588. 'octobre': 9,
  1589. 'nov': 10,
  1590. 'novembre': 10,
  1591. 'déc': 11,
  1592. 'décembre': 11
  1593. };
  1594. } else if (lang == "pt-BR") {
  1595. monthsAbbr = [
  1596. 'Jan',
  1597. 'Fev',
  1598. 'Mar',
  1599. 'Abr',
  1600. 'Mai',
  1601. 'Jun',
  1602. 'Jul',
  1603. 'Ago',
  1604. 'Set',
  1605. 'Out',
  1606. 'Nov',
  1607. 'Dez'
  1608. ];
  1609. monthsFull = [
  1610. 'Janeiro',
  1611. 'Fevereiro',
  1612. 'Março',
  1613. 'Abril',
  1614. 'Maio',
  1615. 'Junho',
  1616. 'Julho',
  1617. 'Agosto',
  1618. 'Setembro',
  1619. 'Outubro',
  1620. 'Novembro',
  1621. 'Dezembro'
  1622. ];
  1623. daysAbbr = [
  1624. 'Dom',
  1625. 'Seg',
  1626. 'Ter',
  1627. 'Qua',
  1628. 'Qui',
  1629. 'Sex',
  1630. 'Sab'
  1631. ];
  1632. daysFull = [
  1633. 'Domingo',
  1634. 'Segunda',
  1635. 'Terça',
  1636. 'Quarta',
  1637. 'Quinta',
  1638. 'Sexta',
  1639. 'Sábado'
  1640. ];
  1641. dayNames = {
  1642. 'do': 0,
  1643. 'dom': 0,
  1644. 'domingo': 0,
  1645. 'se': 1,
  1646. 'seg': 1,
  1647. 'segunda': 1,
  1648. 'te': 2,
  1649. 'ter': 2,
  1650. 'terca': 2,
  1651. 'qa': 3,
  1652. 'qua': 3,
  1653. 'quarta': 3,
  1654. 'qi': 4,
  1655. 'qui': 4,
  1656. 'quinta': 4,
  1657. 'se': 5,
  1658. 'sex': 5,
  1659. 'sexta': 5,
  1660. 'sa': 6,
  1661. 'sab': 6,
  1662. 'sabado': 6
  1663. };
  1664. monthsAll = monthsFull.concat(monthsAbbr);
  1665. daysAll = [
  1666. 'do',
  1667. 'dom',
  1668. 'domingo',
  1669. 'se',
  1670. 'seg',
  1671. 'segunda',
  1672. 'te',
  1673. 'ter',
  1674. 'terça',
  1675. 'qa',
  1676. 'qua',
  1677. 'quarta',
  1678. 'qi',
  1679. 'qui',
  1680. 'quinta',
  1681. 'se',
  1682. 'sex',
  1683. 'sexta',
  1684. 'sa',
  1685. 'sab',
  1686. 'sábado'
  1687. ];
  1688. monthNames = {
  1689. 'jan': 0,
  1690. 'janeiro': 0,
  1691. 'fev': 1,
  1692. 'fevereiro': 1,
  1693. 'mar': 2,
  1694. 'março': 2,
  1695. 'abr': 3,
  1696. 'abril': 3,
  1697. 'mai': 4,
  1698. 'jun': 5,
  1699. 'junho': 5,
  1700. 'jul': 6,
  1701. 'julho': 6,
  1702. 'ago': 7,
  1703. 'agosto': 7,
  1704. 'set': 8,
  1705. 'setembro': 8,
  1706. 'out': 9,
  1707. 'outubro': 9,
  1708. 'nov': 10,
  1709. 'novembro': 10,
  1710. 'dez': 11,
  1711. 'dezembro': 11
  1712. };
  1713. }
  1714. };
  1715. // Are we being imported?..
  1716. if (typeof module !== "undefined" && typeof module.exports === "object") {
  1717. module.exports.language = language;
  1718. } else if (typeof exports === "object") {
  1719. exports.language = language;
  1720. } else if (typeof Date.language === "undefined"){
  1721. // ...if not and if no language, then add statically to Date (for browsers.)
  1722. Date.language = language;
  1723. }
  1724. }());