Requires

Provides

Date.js

Extends the Date native object to include methods useful in managing dates.

License:
MIT-style license
Authors:
Aaron Newton, Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/, Harald Kirshner - mail [at] digitarald.de; http://digitarald.de, Scott Kyle - scott [at] appden.com; http://appden.com
  1. 32
  2. 33
  3. 34
  4. 35
  5. 36
  6. 37
  7. 38
  8. 39
  9. 40
  10. 41
  11. 42
  12. 43
  13. 44
  14. 45
  15. 46
  16. 47
  17. 48
  18. 49
  19. 50
  20. 51
  21. 52
  22. 53
  23. 54
  24. 55
  25. 56
  26. 57
  27. 58
  28. 59
  29. 60
  30. 61
  31. 62
  32. 63
  33. 64
  34. 65
  35. 66
  36. 67
  37. 68
  38. 69
  39. 70
  40. 71
  41. 72
  42. 73
  43. 74
  44. 75
  45. 76
  46. 77
  47. 78
  48. 79
  49. 80
  50. 81
  51. 82
  52. 83
  53. 84
  54. 85
  55. 86
  56. 87
  57. 88
  58. 89
  59. 90
  60. 91
  61. 92
  62. 93
  63. 94
  64. 95
  65. 96
  66. 97
  67. 98
  68. 99
  69. 100
  70. 101
  71. 102
  72. 103
  73. 104
  74. 105
  75. 106
  76. 107
  77. 108
  78. 109
  79. 110
  80. 111
  81. 112
  82. 113
  83. 114
  84. 115
  85. 116
  86. 117
  87. 118
  88. 119
  89. 120
  90. 121
  91. 122
  92. 123
  93. 124
  94. 125
  95. 126
  96. 127
  97. 128
  98. 129
  99. 130
  100. 131
  101. 132
  102. 133
  103. 134
  104. 135
  105. 136
  106. 137
  107. 138
  108. 139
  109. 140
  110. 141
  111. 142
  112. 143
  113. 144
  114. 145
  115. 146
  116. 147
  117. 148
  118. 149
  119. 150
  120. 151
  121. 152
  122. 153
  123. 154
  124. 155
  125. 156
  126. 157
  127. 158
  128. 159
  129. 160
  130. 161
  131. 162
  132. 163
  133. 164
  134. 165
  135. 166
  136. 167
  137. 168
  138. 169
  139. 170
  140. 171
  141. 172
  142. 173
  143. 174
  144. 175
  145. 176
  146. 177
  147. 178
  148. 179
  149. 180
  150. 181
  151. 182
  152. 183
  153. 184
  154. 185
  155. 186
  156. 187
  157. 188
  158. 189
  159. 190
  160. 191
  161. 192
  162. 193
  163. 194
  164. 195
  165. 196
  166. 197
  167. 198
  168. 199
  169. 200
  170. 201
  171. 202
  172. 203
  173. 204
  174. 205
  175. 206
  176. 207
  177. 208
  178. 209
  179. 210
  180. 211
  181. 212
  182. 213
  183. 214
  184. 215
  185. 216
  186. 217
  187. 218
  188. 219
  189. 220
  190. 221
  191. 222
  192. 223
  193. 224
  194. 225
  195. 226
  196. 227
  197. 228
  198. 229
  199. 230
  200. 231
  201. 232
  202. 233
  203. 234
  204. 235
  205. 236
  206. 237
  207. 238
  208. 239
  209. 240
  210. 241
  211. 242
  212. 243
  213. 244
  214. 245
  215. 246
  216. 247
  217. 248
  218. 249
  219. 250
  220. 251
  221. 252
  222. 253
  223. 254
  224. 255
  225. 256
  226. 257
  227. 258
  228. 259
  229. 260
  230. 261
  231. 262
  232. 263
  233. 264
  234. 265
  235. 266
  236. 267
  237. 268
  238. 269
  239. 270
  240. 271
  241. 272
  242. 273
  243. 274
  244. 275
  245. 276
  246. 277
  247. 278
  248. 279
  249. 280
  250. 281
  251. 282
  252. 283
  253. 284
  254. 285
  255. 286
  256. 287
  257. 288
  258. 289
  259. 290
  260. 291
  261. 292
  262. 293
  263. 294
  264. 295
  265. 296
  266. 297
  267. 298
  268. 299
  269. 300
  270. 301
  271. 302
  272. 303
  273. 304
  274. 305
  275. 306
  276. 307
  277. 308
  278. 309
  279. 310
  280. 311
  281. 312
  282. 313
  283. 314
  284. 315
  285. 316
  286. 317
  287. 318
  288. 319
  289. 320
  290. 321
  291. 322
  292. 323
  293. 324
  294. 325
  295. 326
  296. 327
  297. 328
  298. 329
  299. 330
  300. 331
  301. 332
  302. 333
(function(){ var Date = this.Date; Date.Methods = { ms: 'Milliseconds', year: 'FullYear', min: 'Minutes', mo: 'Month', sec: 'Seconds', hr: 'Hours' }; ['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset', 'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear', 'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds', 'UTCMilliseconds'].each(function(method){ Date.Methods[method.toLowerCase()] = method; }); var pad = function(what, length){ return new Array(length - String(what).length + 1).join('0') + what; }; Date.implement({ set: function(prop, value){ switch (typeOf(prop)){ case 'object': for (var p in prop) this.set(p, prop[p]); break; case 'string': prop = prop.toLowerCase(); var m = Date.Methods; if (m[prop]) this['set' + m[prop]](value); } return this; }, get: function(prop){ prop = prop.toLowerCase(); var m = Date.Methods; if (m[prop]) return this['get' + m[prop]](); return null; }, clone: function(){ return new Date(this.get('time')); }, increment: function(interval, times){ interval = interval || 'day'; times = times != null ? times : 1; switch (interval){ case 'year': return this.increment('month', times * 12); case 'month': var d = this.get('date'); this.set('date', 1).set('mo', this.get('mo') + times); return this.set('date', d.min(this.get('lastdayofmonth'))); case 'week': return this.increment('day', times * 7); case 'day': return this.set('date', this.get('date') + times); } if (!Date.units[interval]) throw new Error(interval + ' is not a supported interval'); return this.set('time', this.get('time') + times * Date.units[interval]()); }, decrement: function(interval, times){ return this.increment(interval, -1 * (times != null ? times : 1)); }, isLeapYear: function(){ return Date.isLeapYear(this.get('year')); }, clearTime: function(){ return this.set({hr: 0, min: 0, sec: 0, ms: 0}); }, diff: function(date, resolution){ if (typeOf(date) == 'string') date = Date.parse(date); return ((date - this) / Date.units[resolution || 'day'](3, 3)).toInt(); // non-leap year, 30-day month }, getLastDayOfMonth: function(){ return Date.daysInMonth(this.get('mo'), this.get('year')); }, getDayOfYear: function(){ return (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1) - Date.UTC(this.get('year'), 0, 1)) / Date.units.day(); }, getWeek: function(){ return (this.get('dayofyear') / 7).ceil(); }, getOrdinal: function(day){ return Date.getMsg('ordinal', day || this.get('date')); }, getTimezone: function(){ return this.toString() .replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1') .replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, '$1$2$3'); }, getGMTOffset: function(){ var off = this.get('timezoneOffset'); return ((off > 0) ? '-' : '+') + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2); }, setAMPM: function(ampm){ ampm = ampm.toUpperCase(); var hr = this.get('hr'); if (hr > 11 && ampm == 'AM') return this.decrement('hour', 12); else if (hr < 12 && ampm == 'PM') return this.increment('hour', 12); return this; }, getAMPM: function(){ return (this.get('hr') < 12) ? 'AM' : 'PM'; }, parse: function(str){ this.set('time', Date.parse(str)); return this; }, isValid: function(date){ return !!(date || this).valueOf(); }, format: function(f){ if (!this.isValid()) return 'invalid date'; f = f || '%x %X'; f = formats[f.toLowerCase()] || f; // replace short-hand with actual format var d = this; return f.replace(/%([a-z%])/gi, function($0, $1){ switch ($1){ case 'a': return Date.getMsg('days')[d.get('day')].substr(0, 3); case 'A': return Date.getMsg('days')[d.get('day')]; case 'b': return Date.getMsg('months')[d.get('month')].substr(0, 3); case 'B': return Date.getMsg('months')[d.get('month')]; case 'c': return d.toString(); case 'd': return pad(d.get('date'), 2); case 'e': return d.get('date'); case 'H': return pad(d.get('hr'), 2); case 'I': return ((d.get('hr') % 12) || 12); case 'j': return pad(d.get('dayofyear'), 3); case 'm': return pad((d.get('mo') + 1), 2); case 'M': return pad(d.get('min'), 2); case 'o': return d.get('ordinal'); case 'p': return Date.getMsg(d.get('ampm')); case 'S': return pad(d.get('seconds'), 2); case 'U': return pad(d.get('week'), 2); case 'w': return d.get('day'); case 'x': return d.format(Date.getMsg('shortDate')); case 'X': return d.format(Date.getMsg('shortTime')); case 'y': return d.get('year').toString().substr(2); case 'Y': return d.get('year'); case 'T': return d.get('GMTOffset'); case 'Z': return d.get('Timezone'); case 'z': return pad(d.get('ms')); } return $1; } ); }, toISOString: function(){ return this.format('iso8601'); } }); Date.alias('toJSON', 'toISOString'); Date.alias('compare', 'diff'); Date.alias('strftime', 'format'); var formats = { db: '%Y-%m-%d %H:%M:%S', compact: '%Y%m%dT%H%M%S', iso8601: '%Y-%m-%dT%H:%M:%S%T', rfc822: '%a, %d %b %Y %H:%M:%S %Z', 'short': '%d %b %H:%M', 'long': '%B %d, %Y %H:%M' }; var parsePatterns = []; var nativeParse = Date.parse; var parseWord = function(type, word, num){ var ret = -1; var translated = Date.getMsg(type + 's'); switch (typeOf(word)){ case 'object': ret = translated[word.get(type)]; break; case 'number': ret = translated[word]; if (!ret) throw new Error('Invalid ' + type + ' index: ' + word); break; case 'string': var match = translated.filter(function(name){ return this.test(name); }, new RegExp('^' + word, 'i')); if (!match.length) throw new Error('Invalid ' + type + ' string'); if (match.length > 1) throw new Error('Ambiguous ' + type); ret = match[0]; } return (num) ? translated.indexOf(ret) : ret; }; Date.extend({ getMsg: function(key, args){ return Locale.get('Date.' + key, args); }, units: { ms: Function.from(1), second: Function.from(1000), minute: Function.from(60000), hour: Function.from(3600000), day: Function.from(86400000), week: Function.from(608400000), month: function(month, year){ var d = new Date; return Date.daysInMonth(month != null ? month : d.get('mo'), year != null ? year : d.get('year')) * 86400000; }, year: function(year){ year = year || new Date().get('year'); return Date.isLeapYear(year) ? 31622400000 : 31536000000; } }, daysInMonth: function(month, year){ return [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; }, isLeapYear: function(year){ return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); }, parse: function(from){ var t = typeOf(from); if (t == 'number') return new Date(from); if (t != 'string') return from; from = from.clean(); if (!from.length) return null; var parsed; parsePatterns.some(function(pattern){ var bits = pattern.re.exec(from); return (bits) ? (parsed = pattern.handler(bits)) : false; }); return parsed || new Date(nativeParse(from)); }, parseDay: function(day, num){ return parseWord('day', day, num); }, parseMonth: function(month, num){ return parseWord('month', month, num); }, parseUTC: function(value){ var localDate = new Date(value); var utcSeconds = Date.UTC( localDate.get('year'), localDate.get('mo'), localDate.get('date'), localDate.get('hr'), localDate.get('min'), localDate.get('sec'), localDate.get('ms') ); return new Date(utcSeconds); }, orderIndex: function(unit){ return Date.getMsg('dateOrder').indexOf(unit) + 1; }, defineFormat: function(name, format){ formats[name] = format; }, defineFormats: function(formats){ for (var name in formats) Date.defineFormat(name, formats[name]); },

<1.2compat>

  1. 336
parsePatterns: parsePatterns, // this is deprecated

</1.2compat>

  1. 339
  2. 340
  3. 341
  4. 342
  5. 343
  6. 344
  7. 345
  8. 346
  9. 347
  10. 348
  11. 349
  12. 350
  13. 351
  14. 352
  15. 353
  16. 354
  17. 355
  18. 356
  19. 357
  20. 358
  21. 359
  22. 360
  23. 361
  24. 362
  25. 363
  26. 364
  27. 365
  28. 366
  29. 367
  30. 368
  31. 369
  32. 370
  33. 371
  34. 372
  35. 373
  36. 374
  37. 375
  38. 376
  39. 377
  40. 378
  41. 379
  42. 380
  43. 381
  44. 382
  45. 383
  46. 384
  47. 385
  48. 386
  49. 387
  50. 388
  51. 389
  52. 390
  53. 391
  54. 392
  55. 393
  56. 394
  57. 395
  58. 396
  59. 397
  60. 398
  61. 399
  62. 400
  63. 401
  64. 402
  65. 403
  66. 404
  67. 405
  68. 406
  69. 407
  70. 408
  71. 409
  72. 410
  73. 411
  74. 412
  75. 413
  76. 414
  77. 415
  78. 416
  79. 417
  80. 418
  81. 419
  82. 420
  83. 421
  84. 422
  85. 423
  86. 424
  87. 425
  88. 426
  89. 427
  90. 428
  91. 429
  92. 430
  93. 431
  94. 432
  95. 433
  96. 434
  97. 435
  98. 436
  99. 437
  100. 438
  101. 439
  102. 440
  103. 441
  104. 442
  105. 443
  106. 444
  107. 445
  108. 446
  109. 447
  110. 448
  111. 449
  112. 450
  113. 451
  114. 452
  115. 453
  116. 454
  117. 455
  118. 456
  119. 457
  120. 458
  121. 459
  122. 460
  123. 461
  124. 462
  125. 463
  126. 464
  127. 465
  128. 466
  129. 467
  130. 468
  131. 469
  132. 470
  133. 471
  134. 472
  135. 473
  136. 474
  137. 475
  138. 476
  139. 477
  140. 478
  141. 479
  142. 480
defineParser: function(pattern){ parsePatterns.push((pattern.re && pattern.handler) ? pattern : build(pattern)); }, defineParsers: function(){ Array.flatten(arguments).each(Date.defineParser); }, define2DigitYearStart: function(year){ startYear = year % 100; startCentury = year - startYear; } }); var startCentury = 1900; var startYear = 70; var regexOf = function(type){ return new RegExp('(?:' + Date.getMsg(type).map(function(name){ return name.substr(0, 3); }).join('|') + ')[a-z]*'); }; var replacers = function(key){ switch(key){ case 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first return ((Date.orderIndex('month') == 1) ? '%m[.-/]%d' : '%d[.-/]%m') + '([.-/]%y)?'; case 'X': return '%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%T?'; } return null; }; var keys = { d: /[0-2]?[0-9]|3[01]/, H: /[01]?[0-9]|2[0-3]/, I: /0?[1-9]|1[0-2]/, M: /[0-5]?\d/, s: /\d+/, o: /[a-z]*/, p: /[ap]\.?m\.?/, y: /\d{2}|\d{4}/, Y: /\d{4}/, T: /Z|[+-]\d{2}(?::?\d{2})?/ }; keys.m = keys.I; keys.S = keys.M; var currentLanguage; var recompile = function(language){ currentLanguage = language; keys.a = keys.A = regexOf('days'); keys.b = keys.B = regexOf('months'); parsePatterns.each(function(pattern, i){ if (pattern.format) parsePatterns[i] = build(pattern.format); }); }; var build = function(format){ if (!currentLanguage) return {format: format}; var parsed = []; var re = (format.source || format) // allow format to be regex .replace(/%([a-z])/gi, function($0, $1){ return replacers($1) || $0; } ).replace(/\((?!\?)/g, '(?:') // make all groups non-capturing .replace(/ (?!\?|\*)/g, ',? ') // be forgiving with spaces and commas .replace(/%([a-z%])/gi, function($0, $1){ var p = keys[$1]; if (!p) return $1; parsed.push($1); return '(' + p.source + ')'; } ).replace(/\[a-z\]/gi, '[a-z\\u00c0-\\uffff]'); // handle unicode words return { format: format, re: new RegExp('^' + re + '$', 'i'), handler: function(bits){ bits = bits.slice(1).associate(parsed); var date = new Date().clearTime(); ['d', 'm', 'b', 'B'].each(function(letter){ if (letter in bits) handle.call(date, letter, 1); }); for (var key in bits) handle.call(date, key, bits[key]); return date; } }; }; var handle = function(key, value){ if (!value) return this; switch(key){ case 'a': case 'A': return this.set('day', Date.parseDay(value, true)); case 'b': case 'B': return this.set('mo', Date.parseMonth(value, true)); case 'd': return this.set('date', value); case 'H': case 'I': return this.set('hr', value); case 'm': return this.set('mo', value - 1); case 'M': return this.set('min', value); case 'p': return this.set('ampm', value.replace(/\./g, '')); case 'S': return this.set('sec', value); case 's': return this.set('ms', ('0.' + value) * 1000); case 'w': return this.set('day', value); case 'Y': return this.set('year', value); case 'y': value = +value; if (value < 100) value += startCentury + (value < startYear ? 100 : 0); return this.set('year', value); case 'T': if (value == 'Z') value = '+00'; var offset = value.match(/([+-])(\d{2}):?(\d{2})?/); offset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset(); return this.set('time', this - offset * 60000); } return this; }; Date.defineParsers( '%Y([-./]%m([-./]%d((T| )%X)?)?)?', // "1999-12-31", "1999-12-31 11:59pm", "1999-12-31 23:59:59", ISO8601 '%Y%m%d(T%H(%M%S?)?)?', // "19991231", "19991231T1159", compact '%x( %X)?', // "12/31", "12.31.99", "12-31-1999", "12/31/2008 11:59 PM" '%d%o( %b( %Y)?)?( %X)?', // "31st", "31st December", "31 Dec 1999", "31 Dec 1999 11:59pm" '%b( %d%o)?( %Y)?( %X)?', // Same as above with month and day switched '%Y %b( %d%o( %X)?)?', // Same as above with year coming first '%o %b %d %X %T %Y' // "Thu Oct 22 08:11:23 +0000 2009" ); Locale.addEvent('change', function(language){ if (Locale.get('Date')) recompile(language); }).fireEvent('change', Locale.getCurrent()); })();