momentjs-rails 2.10.6 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -10
  3. data/news.md +3 -0
  4. data/test/dummy/log/test.log +32 -0
  5. data/test/dummy/tmp/cache/assets/D1C/680/sprockets%2F16ed4d5afdb2919596e6f8790e2116c2 +0 -0
  6. data/test/dummy/tmp/cache/assets/D35/CA0/sprockets%2F493e64bce2d302801dc01cf7cd096a58 +0 -0
  7. data/test/dummy/tmp/cache/assets/D3F/5F0/sprockets%2F4a6c53eae7c6e41a69a191578bbb6417 +0 -0
  8. data/test/dummy/tmp/cache/assets/D58/BD0/sprockets%2F4de9ddc9b725c715a54c98697b2528fe +0 -0
  9. data/test/dummy/tmp/cache/assets/D75/510/sprockets%2Fe690787ac522f47a6be024bfcc1767ee +0 -0
  10. data/test/dummy/tmp/cache/assets/E10/250/sprockets%2Fe4badb9ddfda484eb9671bf88567be61 +0 -0
  11. data/test/integration/navigation_test.rb +1 -1
  12. data/vendor/assets/javascripts/moment.js +605 -280
  13. data/vendor/assets/javascripts/moment/af.js +4 -3
  14. data/vendor/assets/javascripts/moment/ar-ma.js +4 -3
  15. data/vendor/assets/javascripts/moment/ar-sa.js +4 -3
  16. data/vendor/assets/javascripts/moment/ar-tn.js +4 -3
  17. data/vendor/assets/javascripts/moment/ar.js +4 -3
  18. data/vendor/assets/javascripts/moment/az.js +4 -3
  19. data/vendor/assets/javascripts/moment/be.js +13 -25
  20. data/vendor/assets/javascripts/moment/bg.js +4 -3
  21. data/vendor/assets/javascripts/moment/bn.js +10 -9
  22. data/vendor/assets/javascripts/moment/bo.js +4 -3
  23. data/vendor/assets/javascripts/moment/br.js +4 -3
  24. data/vendor/assets/javascripts/moment/bs.js +4 -3
  25. data/vendor/assets/javascripts/moment/ca.js +5 -4
  26. data/vendor/assets/javascripts/moment/cs.js +18 -3
  27. data/vendor/assets/javascripts/moment/cv.js +4 -3
  28. data/vendor/assets/javascripts/moment/cy.js +4 -3
  29. data/vendor/assets/javascripts/moment/da.js +4 -3
  30. data/vendor/assets/javascripts/moment/de-at.js +8 -6
  31. data/vendor/assets/javascripts/moment/de.js +8 -6
  32. data/vendor/assets/javascripts/moment/dv.js +99 -0
  33. data/vendor/assets/javascripts/moment/el.js +9 -4
  34. data/vendor/assets/javascripts/moment/en-au.js +8 -4
  35. data/vendor/assets/javascripts/moment/en-ca.js +8 -4
  36. data/vendor/assets/javascripts/moment/en-gb.js +8 -4
  37. data/vendor/assets/javascripts/moment/en-ie.js +70 -0
  38. data/vendor/assets/javascripts/moment/en-nz.js +69 -0
  39. data/vendor/assets/javascripts/moment/eo.js +4 -3
  40. data/vendor/assets/javascripts/moment/es.js +10 -9
  41. data/vendor/assets/javascripts/moment/et.js +4 -3
  42. data/vendor/assets/javascripts/moment/eu.js +4 -3
  43. data/vendor/assets/javascripts/moment/fa.js +4 -3
  44. data/vendor/assets/javascripts/moment/fi.js +4 -3
  45. data/vendor/assets/javascripts/moment/fo.js +4 -3
  46. data/vendor/assets/javascripts/moment/fr-ca.js +4 -3
  47. data/vendor/assets/javascripts/moment/fr-ch.js +62 -0
  48. data/vendor/assets/javascripts/moment/fr.js +4 -3
  49. data/vendor/assets/javascripts/moment/fy.js +4 -3
  50. data/vendor/assets/javascripts/moment/gd.js +86 -0
  51. data/vendor/assets/javascripts/moment/gl.js +4 -3
  52. data/vendor/assets/javascripts/moment/he.js +4 -3
  53. data/vendor/assets/javascripts/moment/hi.js +4 -3
  54. data/vendor/assets/javascripts/moment/hr.js +8 -4
  55. data/vendor/assets/javascripts/moment/hu.js +4 -3
  56. data/vendor/assets/javascripts/moment/hy-am.js +10 -25
  57. data/vendor/assets/javascripts/moment/id.js +4 -3
  58. data/vendor/assets/javascripts/moment/is.js +4 -3
  59. data/vendor/assets/javascripts/moment/it.js +5 -4
  60. data/vendor/assets/javascripts/moment/ja.js +4 -3
  61. data/vendor/assets/javascripts/moment/jv.js +4 -3
  62. data/vendor/assets/javascripts/moment/ka.js +13 -26
  63. data/vendor/assets/javascripts/moment/kk.js +87 -0
  64. data/vendor/assets/javascripts/moment/km.js +5 -4
  65. data/vendor/assets/javascripts/moment/ko.js +4 -3
  66. data/vendor/assets/javascripts/moment/lb.js +4 -3
  67. data/vendor/assets/javascripts/moment/lo.js +69 -0
  68. data/vendor/assets/javascripts/moment/lt.js +14 -23
  69. data/vendor/assets/javascripts/moment/lv.js +4 -3
  70. data/vendor/assets/javascripts/moment/me.js +4 -3
  71. data/vendor/assets/javascripts/moment/mk.js +7 -6
  72. data/vendor/assets/javascripts/moment/ml.js +4 -3
  73. data/vendor/assets/javascripts/moment/mr.js +54 -16
  74. data/vendor/assets/javascripts/moment/ms-my.js +4 -3
  75. data/vendor/assets/javascripts/moment/ms.js +5 -4
  76. data/vendor/assets/javascripts/moment/my.js +4 -3
  77. data/vendor/assets/javascripts/moment/nb.js +10 -9
  78. data/vendor/assets/javascripts/moment/ne.js +18 -19
  79. data/vendor/assets/javascripts/moment/nl.js +4 -3
  80. data/vendor/assets/javascripts/moment/nn.js +7 -6
  81. data/vendor/assets/javascripts/moment/pl.js +5 -4
  82. data/vendor/assets/javascripts/moment/pt-br.js +4 -3
  83. data/vendor/assets/javascripts/moment/pt.js +4 -3
  84. data/vendor/assets/javascripts/moment/ro.js +4 -3
  85. data/vendor/assets/javascripts/moment/ru.js +43 -40
  86. data/vendor/assets/javascripts/moment/se.js +61 -0
  87. data/vendor/assets/javascripts/moment/si.js +5 -3
  88. data/vendor/assets/javascripts/moment/sk.js +4 -11
  89. data/vendor/assets/javascripts/moment/sl.js +4 -3
  90. data/vendor/assets/javascripts/moment/sq.js +4 -3
  91. data/vendor/assets/javascripts/moment/sr-cyrl.js +4 -3
  92. data/vendor/assets/javascripts/moment/sr.js +4 -3
  93. data/vendor/assets/javascripts/moment/sv.js +4 -3
  94. data/vendor/assets/javascripts/moment/sw.js +58 -0
  95. data/vendor/assets/javascripts/moment/ta.js +38 -3
  96. data/vendor/assets/javascripts/moment/te.js +88 -0
  97. data/vendor/assets/javascripts/moment/th.js +4 -3
  98. data/vendor/assets/javascripts/moment/tl-ph.js +4 -3
  99. data/vendor/assets/javascripts/moment/tlh.js +119 -0
  100. data/vendor/assets/javascripts/moment/tr.js +4 -3
  101. data/vendor/assets/javascripts/moment/tzl.js +26 -23
  102. data/vendor/assets/javascripts/moment/tzm-latn.js +4 -3
  103. data/vendor/assets/javascripts/moment/tzm.js +4 -3
  104. data/vendor/assets/javascripts/moment/uk.js +10 -16
  105. data/vendor/assets/javascripts/moment/uz.js +5 -4
  106. data/vendor/assets/javascripts/moment/vi.js +4 -3
  107. data/vendor/assets/javascripts/moment/zh-cn.js +4 -3
  108. data/vendor/assets/javascripts/moment/zh-tw.js +4 -3
  109. metadata +13 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 829a52b9d5e8ef07eca1f128eb4682cea2baaa57
4
- data.tar.gz: dd4293a97731b5191392ea7251f1b18d4dab5909
3
+ metadata.gz: 354d30c82ad5089b4a3ee59bb3d46d14272f3196
4
+ data.tar.gz: 8c45370efde838b27f4b49ae406bbb875362ae4e
5
5
  SHA512:
6
- metadata.gz: a64517a443f5529263dc7c4b05e369459370bfecb941ac19cb75da801ffc4bb717d4bcca7d76898c23c30541e48223385918478bf5bcf82d785dabf03d2c52de
7
- data.tar.gz: 3a27b5df03de322d9043771373d71b19fc961aae62ea131d173bc57decf47b176206c52421cb2eeb76d521d27378deebee36f0f4741d4cdc2a6dadb472049c0f
6
+ metadata.gz: 65438b10f1d20dc30e7dee62610587c139cd5e47a386f4b3550ead83d9af4d6f2f7b91739764c85a31558db170f84181b1bd18261d42f580f9ee9e1bab0c8e56
7
+ data.tar.gz: 70c9163f8f3eed6a2691abee5bfe59e6df662faf46e926a92f0e6a5446c24f6498c19c13a8194e5e68430bf5ffe721e6af97a11be7024b304defce38eb4075d8
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # momentjs-rails
2
2
 
3
- momentjs-rails wraps the [Moment.js](http://momentjs.com/) library in a rails engine for simple
4
- use with the asset pipeline provided by Rails 3.1 and higher. The gem includes the development (non-minified)
5
- source for ease of exploration. The asset pipeline will minify in production.
6
-
7
- Moment.js is "a lightweight javascript date library for parsing, manipulating, and formatting dates."
8
- Moment.js does not modify the native Date object. Rather, it creates a wrapper for it. Please see the
3
+ momentjs-rails wraps the [Moment.js](http://momentjs.com/) library in a rails
4
+ engine for simple use with the asset pipeline provided by Rails 3.1 and higher.
5
+ The gem includes the development (non-minified) source for ease of exploration.
6
+ The asset pipeline will minify in production.
7
+
8
+ Moment.js is "a lightweight javascript date library for parsing, manipulating,
9
+ and formatting dates." Moment.js does not modify the native Date object. Rather,
10
+ it creates a wrapper for it. Please see the
9
11
  [documentation](http://momentjs.com/docs/) for details.
10
12
 
11
13
  ## Usage
@@ -24,8 +26,9 @@ If you want to include a localization file, also add the following directive:
24
26
 
25
27
  ## Versioning
26
28
 
27
- momentjs-rails 2.10.6 == Moment.js 2.10.6
29
+ momentjs-rails 2.11.0 == Moment.js 2.11.0
28
30
 
29
- Every attempt is made to mirror the currently shipping Moment.js version number wherever possible.
30
- The major, minor, and patch version numbers will always represent the Moment.js version. Should a gem
31
- bug be discovered, a 4th version identifier will be added and incremented.
31
+ Every attempt is made to mirror the currently shipping Moment.js version number
32
+ wherever possible. The major, minor, and patch version numbers will always
33
+ represent the Moment.js version. Should a gem bug be discovered, a 4th version
34
+ identifier will be added and incremented.
data/news.md CHANGED
@@ -1,3 +1,6 @@
1
+ ### Version 2.11.0 (2016-01-08)
2
+ - Updated Moment.js to 2.11.0
3
+
1
4
  ### Version 2.10.6 (2015-10-06)
2
5
  - Updated Moment.js to 2.10.6
3
6
 
@@ -6,3 +6,35 @@ Compiled moment/fr.js (0ms) (pid 93192)
6
6
  Served asset /moment/fr.js - 200 OK (4ms)
7
7
  Started GET "/assets/moment.js" for 127.0.0.1 at 2015-10-07 10:20:23 -0400
8
8
  Served asset /moment.js - 200 OK (0ms)
9
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:15:32 -0500
10
+ Compiled moment.js (2ms) (pid 31945)
11
+ Served asset /moment.js - 200 OK (17ms)
12
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2016-01-08 09:15:32 -0500
13
+ Compiled moment/fr.js (0ms) (pid 31945)
14
+ Served asset /moment/fr.js - 200 OK (5ms)
15
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:15:32 -0500
16
+ Served asset /moment.js - 200 OK (0ms)
17
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:15:48 -0500
18
+ Served asset /moment.js - 200 OK (3ms)
19
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2016-01-08 09:15:48 -0500
20
+ Served asset /moment/fr.js - 200 OK (1ms)
21
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:15:48 -0500
22
+ Served asset /moment.js - 200 OK (0ms)
23
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:17:09 -0500
24
+ Served asset /moment.js - 200 OK (3ms)
25
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2016-01-08 09:17:09 -0500
26
+ Served asset /moment/fr.js - 200 OK (1ms)
27
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:17:09 -0500
28
+ Served asset /moment.js - 200 OK (0ms)
29
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:17:42 -0500
30
+ Served asset /moment.js - 200 OK (3ms)
31
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2016-01-08 09:17:42 -0500
32
+ Served asset /moment/fr.js - 200 OK (1ms)
33
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:17:42 -0500
34
+ Served asset /moment.js - 200 OK (0ms)
35
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:20:12 -0500
36
+ Served asset /moment.js - 200 OK (3ms)
37
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2016-01-08 09:20:12 -0500
38
+ Served asset /moment/fr.js - 200 OK (1ms)
39
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2016-01-08 09:20:12 -0500
40
+ Served asset /moment.js - 200 OK (0ms)
@@ -8,7 +8,7 @@ class NavigationTest < ActionDispatch::IntegrationTest
8
8
 
9
9
  test 'momentjs response is for the expected version' do
10
10
  get '/assets/moment.js'
11
- assert_match(/utils_hooks__hooks.version = '2\.10\.6'/, @response.body)
11
+ assert_match(/utils_hooks__hooks.version = '2\.11\.0'/, @response.body)
12
12
  end
13
13
 
14
14
  test 'can access momentjs translation' do
@@ -1,10 +1,10 @@
1
1
  //! moment.js
2
- //! version : 2.10.6
2
+ //! version : 2.11.0
3
3
  //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4
4
  //! license : MIT
5
5
  //! momentjs.com
6
6
 
7
- (function (global, factory) {
7
+ ;(function (global, factory) {
8
8
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
9
9
  typeof define === 'function' && define.amd ? define(factory) :
10
10
  global.moment = factory()
@@ -121,39 +121,45 @@
121
121
  return m;
122
122
  }
123
123
 
124
+ function isUndefined(input) {
125
+ return input === void 0;
126
+ }
127
+
128
+ // Plugins that add properties should also add the key here (null value),
129
+ // so we can properly clone ourselves.
124
130
  var momentProperties = utils_hooks__hooks.momentProperties = [];
125
131
 
126
132
  function copyConfig(to, from) {
127
133
  var i, prop, val;
128
134
 
129
- if (typeof from._isAMomentObject !== 'undefined') {
135
+ if (!isUndefined(from._isAMomentObject)) {
130
136
  to._isAMomentObject = from._isAMomentObject;
131
137
  }
132
- if (typeof from._i !== 'undefined') {
138
+ if (!isUndefined(from._i)) {
133
139
  to._i = from._i;
134
140
  }
135
- if (typeof from._f !== 'undefined') {
141
+ if (!isUndefined(from._f)) {
136
142
  to._f = from._f;
137
143
  }
138
- if (typeof from._l !== 'undefined') {
144
+ if (!isUndefined(from._l)) {
139
145
  to._l = from._l;
140
146
  }
141
- if (typeof from._strict !== 'undefined') {
147
+ if (!isUndefined(from._strict)) {
142
148
  to._strict = from._strict;
143
149
  }
144
- if (typeof from._tzm !== 'undefined') {
150
+ if (!isUndefined(from._tzm)) {
145
151
  to._tzm = from._tzm;
146
152
  }
147
- if (typeof from._isUTC !== 'undefined') {
153
+ if (!isUndefined(from._isUTC)) {
148
154
  to._isUTC = from._isUTC;
149
155
  }
150
- if (typeof from._offset !== 'undefined') {
156
+ if (!isUndefined(from._offset)) {
151
157
  to._offset = from._offset;
152
158
  }
153
- if (typeof from._pf !== 'undefined') {
159
+ if (!isUndefined(from._pf)) {
154
160
  to._pf = getParsingFlags(from);
155
161
  }
156
- if (typeof from._locale !== 'undefined') {
162
+ if (!isUndefined(from._locale)) {
157
163
  to._locale = from._locale;
158
164
  }
159
165
 
@@ -161,7 +167,7 @@
161
167
  for (i in momentProperties) {
162
168
  prop = momentProperties[i];
163
169
  val = from[prop];
164
- if (typeof val !== 'undefined') {
170
+ if (!isUndefined(val)) {
165
171
  to[prop] = val;
166
172
  }
167
173
  }
@@ -208,6 +214,7 @@
208
214
  return value;
209
215
  }
210
216
 
217
+ // compare two arrays, return the number of differences
211
218
  function compareArrays(array1, array2, dontConvert) {
212
219
  var len = Math.min(array1.length, array2.length),
213
220
  lengthDiff = Math.abs(array1.length - array2.length),
@@ -225,6 +232,7 @@
225
232
  function Locale() {
226
233
  }
227
234
 
235
+ // internal storage for locale config files
228
236
  var locales = {};
229
237
  var globalLocale;
230
238
 
@@ -262,7 +270,7 @@
262
270
  function loadLocale(name) {
263
271
  var oldLocale = null;
264
272
  // TODO: Find a better way to register and load all the locales in Node
265
- if (!locales[name] && typeof module !== 'undefined' &&
273
+ if (!locales[name] && !isUndefined(module) &&
266
274
  module && module.exports) {
267
275
  try {
268
276
  oldLocale = globalLocale._abbr;
@@ -281,7 +289,7 @@
281
289
  function locale_locales__getSetGlobalLocale (key, values) {
282
290
  var data;
283
291
  if (key) {
284
- if (typeof values === 'undefined') {
292
+ if (isUndefined(values)) {
285
293
  data = locale_locales__getLocale(key);
286
294
  }
287
295
  else {
@@ -366,6 +374,10 @@
366
374
  return normalizedInput;
367
375
  }
368
376
 
377
+ function isFunction(input) {
378
+ return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
379
+ }
380
+
369
381
  function makeGetSet (unit, keepTime) {
370
382
  return function (value) {
371
383
  if (value != null) {
@@ -379,11 +391,14 @@
379
391
  }
380
392
 
381
393
  function get_set__get (mom, unit) {
382
- return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
394
+ return mom.isValid() ?
395
+ mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
383
396
  }
384
397
 
385
398
  function get_set__set (mom, unit, value) {
386
- return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
399
+ if (mom.isValid()) {
400
+ mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
401
+ }
387
402
  }
388
403
 
389
404
  // MOMENTS
@@ -396,7 +411,7 @@
396
411
  }
397
412
  } else {
398
413
  units = normalizeUnits(units);
399
- if (typeof this[units] === 'function') {
414
+ if (isFunction(this[units])) {
400
415
  return this[units](value);
401
416
  }
402
417
  }
@@ -411,7 +426,7 @@
411
426
  Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
412
427
  }
413
428
 
414
- var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
429
+ var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
415
430
 
416
431
  var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
417
432
 
@@ -507,6 +522,8 @@
507
522
  var match4 = /\d{4}/; // 0000 - 9999
508
523
  var match6 = /[+-]?\d{6}/; // -999999 - 999999
509
524
  var match1to2 = /\d\d?/; // 0 - 99
525
+ var match3to4 = /\d\d\d\d?/; // 999 - 9999
526
+ var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
510
527
  var match1to3 = /\d{1,3}/; // 0 - 999
511
528
  var match1to4 = /\d{1,4}/; // 0 - 9999
512
529
  var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
@@ -515,20 +532,16 @@
515
532
  var matchSigned = /[+-]?\d+/; // -inf - inf
516
533
 
517
534
  var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
535
+ var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
518
536
 
519
537
  var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
520
538
 
521
539
  // any word (or two) characters or numbers including two/three word month in arabic.
522
- var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
540
+ // includes scottish gaelic two word and hyphenated months
541
+ var matchWord = /[0-9]*(a[mn]\s?)?['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\-]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
523
542
 
524
- var regexes = {};
525
-
526
- function isFunction (sth) {
527
- // https://github.com/moment/moment/issues/2325
528
- return typeof sth === 'function' &&
529
- Object.prototype.toString.call(sth) === '[object Function]';
530
- }
531
543
 
544
+ var regexes = {};
532
545
 
533
546
  function addRegexToken (token, regex, strictRegex) {
534
547
  regexes[token] = isFunction(regex) ? regex : function (isStrict) {
@@ -588,6 +601,8 @@
588
601
  var MINUTE = 4;
589
602
  var SECOND = 5;
590
603
  var MILLISECOND = 6;
604
+ var WEEK = 7;
605
+ var WEEKDAY = 8;
591
606
 
592
607
  function daysInMonth(year, month) {
593
608
  return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
@@ -634,14 +649,17 @@
634
649
 
635
650
  // LOCALES
636
651
 
652
+ var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
637
653
  var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
638
- function localeMonths (m) {
639
- return this._months[m.month()];
654
+ function localeMonths (m, format) {
655
+ return isArray(this._months) ? this._months[m.month()] :
656
+ this._months[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
640
657
  }
641
658
 
642
- var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
643
- function localeMonthsShort (m) {
644
- return this._monthsShort[m.month()];
659
+ var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sept_Oct_Nov_Dec'.split('_');
660
+ function localeMonthsShort (m, format) {
661
+ return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
662
+ this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
645
663
  }
646
664
 
647
665
  function localeMonthsParse (monthName, format, strict) {
@@ -680,6 +698,11 @@
680
698
  function setMonth (mom, value) {
681
699
  var dayOfMonth;
682
700
 
701
+ if (!mom.isValid()) {
702
+ // No op
703
+ return mom;
704
+ }
705
+
683
706
  // TODO: Move this out of here!
684
707
  if (typeof value === 'string') {
685
708
  value = mom.localeData().monthsParse(value);
@@ -725,6 +748,12 @@
725
748
  if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
726
749
  overflow = DATE;
727
750
  }
751
+ if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
752
+ overflow = WEEK;
753
+ }
754
+ if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
755
+ overflow = WEEKDAY;
756
+ }
728
757
 
729
758
  getParsingFlags(m).overflow = overflow;
730
759
  }
@@ -733,7 +762,7 @@
733
762
  }
734
763
 
735
764
  function warn(msg) {
736
- if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
765
+ if (utils_hooks__hooks.suppressDeprecationWarnings === false && !isUndefined(console) && console.warn) {
737
766
  console.warn('Deprecation warning: ' + msg);
738
767
  }
739
768
  }
@@ -743,7 +772,7 @@
743
772
 
744
773
  return extend(function () {
745
774
  if (firstTime) {
746
- warn(msg + '\n' + (new Error()).stack);
775
+ warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
747
776
  firstTime = false;
748
777
  }
749
778
  return fn.apply(this, arguments);
@@ -761,22 +790,39 @@
761
790
 
762
791
  utils_hooks__hooks.suppressDeprecationWarnings = false;
763
792
 
764
- var from_string__isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
793
+ // iso 8601 regex
794
+ // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
795
+ var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
796
+ var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
797
+
798
+ var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
765
799
 
766
800
  var isoDates = [
767
- ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
768
- ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
769
- ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
770
- ['GGGG-[W]WW', /\d{4}-W\d{2}/],
771
- ['YYYY-DDD', /\d{4}-\d{3}/]
801
+ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
802
+ ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
803
+ ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
804
+ ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
805
+ ['YYYY-DDD', /\d{4}-\d{3}/],
806
+ ['YYYY-MM', /\d{4}-\d\d/, false],
807
+ ['YYYYYYMMDD', /[+-]\d{10}/],
808
+ ['YYYYMMDD', /\d{8}/],
809
+ // YYYYMM is NOT allowed by the standard
810
+ ['GGGG[W]WWE', /\d{4}W\d{3}/],
811
+ ['GGGG[W]WW', /\d{4}W\d{2}/, false],
812
+ ['YYYYDDD', /\d{7}/]
772
813
  ];
773
814
 
774
815
  // iso time formats and regexes
775
816
  var isoTimes = [
776
- ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
777
- ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
778
- ['HH:mm', /(T| )\d\d:\d\d/],
779
- ['HH', /(T| )\d\d/]
817
+ ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
818
+ ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
819
+ ['HH:mm:ss', /\d\d:\d\d:\d\d/],
820
+ ['HH:mm', /\d\d:\d\d/],
821
+ ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
822
+ ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
823
+ ['HHmmss', /\d\d\d\d\d\d/],
824
+ ['HHmm', /\d\d\d\d/],
825
+ ['HH', /\d\d/]
780
826
  ];
781
827
 
782
828
  var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
@@ -785,26 +831,49 @@
785
831
  function configFromISO(config) {
786
832
  var i, l,
787
833
  string = config._i,
788
- match = from_string__isoRegex.exec(string);
834
+ match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
835
+ allowTime, dateFormat, timeFormat, tzFormat;
789
836
 
790
837
  if (match) {
791
838
  getParsingFlags(config).iso = true;
839
+
792
840
  for (i = 0, l = isoDates.length; i < l; i++) {
793
- if (isoDates[i][1].exec(string)) {
794
- config._f = isoDates[i][0];
841
+ if (isoDates[i][1].exec(match[1])) {
842
+ dateFormat = isoDates[i][0];
843
+ allowTime = isoDates[i][2] !== false;
795
844
  break;
796
845
  }
797
846
  }
798
- for (i = 0, l = isoTimes.length; i < l; i++) {
799
- if (isoTimes[i][1].exec(string)) {
800
- // match[6] should be 'T' or space
801
- config._f += (match[6] || ' ') + isoTimes[i][0];
802
- break;
847
+ if (dateFormat == null) {
848
+ config._isValid = false;
849
+ return;
850
+ }
851
+ if (match[3]) {
852
+ for (i = 0, l = isoTimes.length; i < l; i++) {
853
+ if (isoTimes[i][1].exec(match[3])) {
854
+ // match[2] should be 'T' or space
855
+ timeFormat = (match[2] || ' ') + isoTimes[i][0];
856
+ break;
857
+ }
803
858
  }
859
+ if (timeFormat == null) {
860
+ config._isValid = false;
861
+ return;
862
+ }
863
+ }
864
+ if (!allowTime && timeFormat != null) {
865
+ config._isValid = false;
866
+ return;
804
867
  }
805
- if (string.match(matchOffset)) {
806
- config._f += 'Z';
868
+ if (match[4]) {
869
+ if (tzRegex.exec(match[4])) {
870
+ tzFormat = 'Z';
871
+ } else {
872
+ config._isValid = false;
873
+ return;
874
+ }
807
875
  }
876
+ config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
808
877
  configFromStringAndFormat(config);
809
878
  } else {
810
879
  config._isValid = false;
@@ -842,8 +911,8 @@
842
911
  //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
843
912
  var date = new Date(y, m, d, h, M, s, ms);
844
913
 
845
- //the date constructor doesn't accept years < 1970
846
- if (y < 1970) {
914
+ //the date constructor remaps years 0-99 to 1900-1999
915
+ if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
847
916
  date.setFullYear(y);
848
917
  }
849
918
  return date;
@@ -851,12 +920,16 @@
851
920
 
852
921
  function createUTCDate (y) {
853
922
  var date = new Date(Date.UTC.apply(null, arguments));
854
- if (y < 1970) {
923
+
924
+ //the Date.UTC function remaps years 0-99 to 1900-1999
925
+ if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
855
926
  date.setUTCFullYear(y);
856
927
  }
857
928
  return date;
858
929
  }
859
930
 
931
+ // FORMATTING
932
+
860
933
  addFormatToken(0, ['YY', 2], 0, function () {
861
934
  return this.year() % 100;
862
935
  });
@@ -909,124 +982,66 @@
909
982
  return isLeapYear(this.year());
910
983
  }
911
984
 
912
- addFormatToken('w', ['ww', 2], 'wo', 'week');
913
- addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
914
-
915
- // ALIASES
916
-
917
- addUnitAlias('week', 'w');
918
- addUnitAlias('isoWeek', 'W');
919
-
920
- // PARSING
921
-
922
- addRegexToken('w', match1to2);
923
- addRegexToken('ww', match1to2, match2);
924
- addRegexToken('W', match1to2);
925
- addRegexToken('WW', match1to2, match2);
926
-
927
- addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
928
- week[token.substr(0, 1)] = toInt(input);
929
- });
930
-
931
- // HELPERS
985
+ // start-of-first-week - start-of-year
986
+ function firstWeekOffset(year, dow, doy) {
987
+ var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
988
+ fwd = 7 + dow - doy,
989
+ // first-week day local weekday -- which local weekday is fwd
990
+ fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
932
991
 
933
- // firstDayOfWeek 0 = sun, 6 = sat
934
- // the day of the week that starts the week
935
- // (usually sunday or monday)
936
- // firstDayOfWeekOfYear 0 = sun, 6 = sat
937
- // the first week is the week that contains the first
938
- // of this day of the week
939
- // (eg. ISO weeks use thursday (4))
940
- function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
941
- var end = firstDayOfWeekOfYear - firstDayOfWeek,
942
- daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
943
- adjustedMoment;
944
-
945
-
946
- if (daysToDayOfWeek > end) {
947
- daysToDayOfWeek -= 7;
948
- }
992
+ return -fwdlw + fwd - 1;
993
+ }
949
994
 
950
- if (daysToDayOfWeek < end - 7) {
951
- daysToDayOfWeek += 7;
995
+ //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
996
+ function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
997
+ var localWeekday = (7 + weekday - dow) % 7,
998
+ weekOffset = firstWeekOffset(year, dow, doy),
999
+ dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
1000
+ resYear, resDayOfYear;
1001
+
1002
+ if (dayOfYear <= 0) {
1003
+ resYear = year - 1;
1004
+ resDayOfYear = daysInYear(resYear) + dayOfYear;
1005
+ } else if (dayOfYear > daysInYear(year)) {
1006
+ resYear = year + 1;
1007
+ resDayOfYear = dayOfYear - daysInYear(year);
1008
+ } else {
1009
+ resYear = year;
1010
+ resDayOfYear = dayOfYear;
952
1011
  }
953
1012
 
954
- adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');
955
1013
  return {
956
- week: Math.ceil(adjustedMoment.dayOfYear() / 7),
957
- year: adjustedMoment.year()
1014
+ year: resYear,
1015
+ dayOfYear: resDayOfYear
958
1016
  };
959
1017
  }
960
1018
 
961
- // LOCALES
962
-
963
- function localeWeek (mom) {
964
- return weekOfYear(mom, this._week.dow, this._week.doy).week;
965
- }
966
-
967
- var defaultLocaleWeek = {
968
- dow : 0, // Sunday is the first day of the week.
969
- doy : 6 // The week that contains Jan 1st is the first week of the year.
970
- };
971
-
972
- function localeFirstDayOfWeek () {
973
- return this._week.dow;
974
- }
975
-
976
- function localeFirstDayOfYear () {
977
- return this._week.doy;
978
- }
979
-
980
- // MOMENTS
981
-
982
- function getSetWeek (input) {
983
- var week = this.localeData().week(this);
984
- return input == null ? week : this.add((input - week) * 7, 'd');
985
- }
986
-
987
- function getSetISOWeek (input) {
988
- var week = weekOfYear(this, 1, 4).week;
989
- return input == null ? week : this.add((input - week) * 7, 'd');
990
- }
991
-
992
- addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
993
-
994
- // ALIASES
995
-
996
- addUnitAlias('dayOfYear', 'DDD');
997
-
998
- // PARSING
999
-
1000
- addRegexToken('DDD', match1to3);
1001
- addRegexToken('DDDD', match3);
1002
- addParseToken(['DDD', 'DDDD'], function (input, array, config) {
1003
- config._dayOfYear = toInt(input);
1004
- });
1005
-
1006
- // HELPERS
1019
+ function weekOfYear(mom, dow, doy) {
1020
+ var weekOffset = firstWeekOffset(mom.year(), dow, doy),
1021
+ week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
1022
+ resWeek, resYear;
1007
1023
 
1008
- //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1009
- function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
1010
- var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
1011
- if (d < firstDayOfWeek) {
1012
- d += 7;
1024
+ if (week < 1) {
1025
+ resYear = mom.year() - 1;
1026
+ resWeek = week + weeksInYear(resYear, dow, doy);
1027
+ } else if (week > weeksInYear(mom.year(), dow, doy)) {
1028
+ resWeek = week - weeksInYear(mom.year(), dow, doy);
1029
+ resYear = mom.year() + 1;
1030
+ } else {
1031
+ resYear = mom.year();
1032
+ resWeek = week;
1013
1033
  }
1014
1034
 
1015
- weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
1016
-
1017
- dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
1018
-
1019
1035
  return {
1020
- year: dayOfYear > 0 ? year : year - 1,
1021
- dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
1036
+ week: resWeek,
1037
+ year: resYear
1022
1038
  };
1023
1039
  }
1024
1040
 
1025
- // MOMENTS
1026
-
1027
- function getSetDayOfYear (input) {
1028
- var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
1029
- return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
1041
+ function weeksInYear(year, dow, doy) {
1042
+ var weekOffset = firstWeekOffset(year, dow, doy),
1043
+ weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
1044
+ return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1030
1045
  }
1031
1046
 
1032
1047
  // Pick the first defined of two or three arguments.
@@ -1041,11 +1056,12 @@
1041
1056
  }
1042
1057
 
1043
1058
  function currentDateArray(config) {
1044
- var now = new Date();
1059
+ // hooks is actually the exported moment object
1060
+ var nowValue = new Date(utils_hooks__hooks.now());
1045
1061
  if (config._useUTC) {
1046
- return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];
1062
+ return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
1047
1063
  }
1048
- return [now.getFullYear(), now.getMonth(), now.getDate()];
1064
+ return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
1049
1065
  }
1050
1066
 
1051
1067
  // convert an array to a date.
@@ -1115,7 +1131,7 @@
1115
1131
  }
1116
1132
 
1117
1133
  function dayOfYearFromWeekInfo(config) {
1118
- var w, weekYear, week, weekday, dow, doy, temp;
1134
+ var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
1119
1135
 
1120
1136
  w = config._w;
1121
1137
  if (w.GG != null || w.W != null || w.E != null) {
@@ -1129,6 +1145,9 @@
1129
1145
  weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
1130
1146
  week = defaults(w.W, 1);
1131
1147
  weekday = defaults(w.E, 1);
1148
+ if (weekday < 1 || weekday > 7) {
1149
+ weekdayOverflow = true;
1150
+ }
1132
1151
  } else {
1133
1152
  dow = config._locale._week.dow;
1134
1153
  doy = config._locale._week.doy;
@@ -1139,23 +1158,32 @@
1139
1158
  if (w.d != null) {
1140
1159
  // weekday -- low day numbers are considered next week
1141
1160
  weekday = w.d;
1142
- if (weekday < dow) {
1143
- ++week;
1161
+ if (weekday < 0 || weekday > 6) {
1162
+ weekdayOverflow = true;
1144
1163
  }
1145
1164
  } else if (w.e != null) {
1146
1165
  // local weekday -- counting starts from begining of week
1147
1166
  weekday = w.e + dow;
1167
+ if (w.e < 0 || w.e > 6) {
1168
+ weekdayOverflow = true;
1169
+ }
1148
1170
  } else {
1149
1171
  // default to begining of week
1150
1172
  weekday = dow;
1151
1173
  }
1152
1174
  }
1153
- temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
1154
-
1155
- config._a[YEAR] = temp.year;
1156
- config._dayOfYear = temp.dayOfYear;
1175
+ if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
1176
+ getParsingFlags(config)._overflowWeeks = true;
1177
+ } else if (weekdayOverflow != null) {
1178
+ getParsingFlags(config)._overflowWeekday = true;
1179
+ } else {
1180
+ temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
1181
+ config._a[YEAR] = temp.year;
1182
+ config._dayOfYear = temp.dayOfYear;
1183
+ }
1157
1184
  }
1158
1185
 
1186
+ // constant that refers to the ISO standard
1159
1187
  utils_hooks__hooks.ISO_8601 = function () {};
1160
1188
 
1161
1189
  // date from string and format string
@@ -1248,6 +1276,7 @@
1248
1276
  }
1249
1277
  }
1250
1278
 
1279
+ // date from string and array of format strings
1251
1280
  function configFromStringAndArray(config) {
1252
1281
  var tempConfig,
1253
1282
  bestMoment,
@@ -1298,7 +1327,9 @@
1298
1327
  }
1299
1328
 
1300
1329
  var i = normalizeObjectUnits(config._i);
1301
- config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];
1330
+ config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
1331
+ return obj && parseInt(obj, 10);
1332
+ });
1302
1333
 
1303
1334
  configFromArray(config);
1304
1335
  }
@@ -1340,13 +1371,17 @@
1340
1371
  configFromInput(config);
1341
1372
  }
1342
1373
 
1374
+ if (!valid__isValid(config)) {
1375
+ config._d = null;
1376
+ }
1377
+
1343
1378
  return config;
1344
1379
  }
1345
1380
 
1346
1381
  function configFromInput(config) {
1347
1382
  var input = config._i;
1348
1383
  if (input === undefined) {
1349
- config._d = new Date();
1384
+ config._d = new Date(utils_hooks__hooks.now());
1350
1385
  } else if (isDate(input)) {
1351
1386
  config._d = new Date(+input);
1352
1387
  } else if (typeof input === 'string') {
@@ -1393,7 +1428,11 @@
1393
1428
  'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
1394
1429
  function () {
1395
1430
  var other = local__createLocal.apply(null, arguments);
1396
- return other < this ? this : other;
1431
+ if (this.isValid() && other.isValid()) {
1432
+ return other < this ? this : other;
1433
+ } else {
1434
+ return valid__createInvalid();
1435
+ }
1397
1436
  }
1398
1437
  );
1399
1438
 
@@ -1401,7 +1440,11 @@
1401
1440
  'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
1402
1441
  function () {
1403
1442
  var other = local__createLocal.apply(null, arguments);
1404
- return other > this ? this : other;
1443
+ if (this.isValid() && other.isValid()) {
1444
+ return other > this ? this : other;
1445
+ } else {
1446
+ return valid__createInvalid();
1447
+ }
1405
1448
  }
1406
1449
  );
1407
1450
 
@@ -1440,6 +1483,10 @@
1440
1483
  return pickBy('isAfter', args);
1441
1484
  }
1442
1485
 
1486
+ var now = Date.now || function () {
1487
+ return +(new Date());
1488
+ };
1489
+
1443
1490
  function Duration (duration) {
1444
1491
  var normalizedInput = normalizeObjectUnits(duration),
1445
1492
  years = normalizedInput.year || 0,
@@ -1479,6 +1526,8 @@
1479
1526
  return obj instanceof Duration;
1480
1527
  }
1481
1528
 
1529
+ // FORMATTING
1530
+
1482
1531
  function offset (token, separator) {
1483
1532
  addFormatToken(token, 0, 0, function () {
1484
1533
  var offset = this.utcOffset();
@@ -1496,11 +1545,11 @@
1496
1545
 
1497
1546
  // PARSING
1498
1547
 
1499
- addRegexToken('Z', matchOffset);
1500
- addRegexToken('ZZ', matchOffset);
1548
+ addRegexToken('Z', matchShortOffset);
1549
+ addRegexToken('ZZ', matchShortOffset);
1501
1550
  addParseToken(['Z', 'ZZ'], function (input, array, config) {
1502
1551
  config._useUTC = true;
1503
- config._tzm = offsetFromString(input);
1552
+ config._tzm = offsetFromString(matchShortOffset, input);
1504
1553
  });
1505
1554
 
1506
1555
  // HELPERS
@@ -1510,8 +1559,8 @@
1510
1559
  // '-1530' > ['-15', '30']
1511
1560
  var chunkOffset = /([\+\-]|\d\d)/gi;
1512
1561
 
1513
- function offsetFromString(string) {
1514
- var matches = ((string || '').match(matchOffset) || []);
1562
+ function offsetFromString(matcher, string) {
1563
+ var matches = ((string || '').match(matcher) || []);
1515
1564
  var chunk = matches[matches.length - 1] || [];
1516
1565
  var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
1517
1566
  var minutes = +(parts[1] * 60) + toInt(parts[2]);
@@ -1561,11 +1610,13 @@
1561
1610
  function getSetOffset (input, keepLocalTime) {
1562
1611
  var offset = this._offset || 0,
1563
1612
  localAdjust;
1613
+ if (!this.isValid()) {
1614
+ return input != null ? this : NaN;
1615
+ }
1564
1616
  if (input != null) {
1565
1617
  if (typeof input === 'string') {
1566
- input = offsetFromString(input);
1567
- }
1568
- if (Math.abs(input) < 16) {
1618
+ input = offsetFromString(matchShortOffset, input);
1619
+ } else if (Math.abs(input) < 16) {
1569
1620
  input = input * 60;
1570
1621
  }
1571
1622
  if (!this._isUTC && keepLocalTime) {
@@ -1625,12 +1676,15 @@
1625
1676
  if (this._tzm) {
1626
1677
  this.utcOffset(this._tzm);
1627
1678
  } else if (typeof this._i === 'string') {
1628
- this.utcOffset(offsetFromString(this._i));
1679
+ this.utcOffset(offsetFromString(matchOffset, this._i));
1629
1680
  }
1630
1681
  return this;
1631
1682
  }
1632
1683
 
1633
1684
  function hasAlignedHourOffset (input) {
1685
+ if (!this.isValid()) {
1686
+ return false;
1687
+ }
1634
1688
  input = input ? local__createLocal(input).utcOffset() : 0;
1635
1689
 
1636
1690
  return (this.utcOffset() - input) % 60 === 0;
@@ -1644,7 +1698,7 @@
1644
1698
  }
1645
1699
 
1646
1700
  function isDaylightSavingTimeShifted () {
1647
- if (typeof this._isDSTShifted !== 'undefined') {
1701
+ if (!isUndefined(this._isDSTShifted)) {
1648
1702
  return this._isDSTShifted;
1649
1703
  }
1650
1704
 
@@ -1665,22 +1719,23 @@
1665
1719
  }
1666
1720
 
1667
1721
  function isLocal () {
1668
- return !this._isUTC;
1722
+ return this.isValid() ? !this._isUTC : false;
1669
1723
  }
1670
1724
 
1671
1725
  function isUtcOffset () {
1672
- return this._isUTC;
1726
+ return this.isValid() ? this._isUTC : false;
1673
1727
  }
1674
1728
 
1675
1729
  function isUtc () {
1676
- return this._isUTC && this._offset === 0;
1730
+ return this.isValid() ? this._isUTC && this._offset === 0 : false;
1677
1731
  }
1678
1732
 
1679
- var aspNetRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/;
1733
+ // ASP.NET json date format regex
1734
+ var aspNetRegex = /(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/;
1680
1735
 
1681
1736
  // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
1682
1737
  // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
1683
- var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;
1738
+ var isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;
1684
1739
 
1685
1740
  function create__createDuration (input, key) {
1686
1741
  var duration = input,
@@ -1713,7 +1768,7 @@
1713
1768
  s : toInt(match[SECOND]) * sign,
1714
1769
  ms : toInt(match[MILLISECOND]) * sign
1715
1770
  };
1716
- } else if (!!(match = create__isoRegex.exec(input))) {
1771
+ } else if (!!(match = isoRegex.exec(input))) {
1717
1772
  sign = (match[1] === '-') ? -1 : 1;
1718
1773
  duration = {
1719
1774
  y : parseIso(match[2], sign),
@@ -1770,6 +1825,10 @@
1770
1825
 
1771
1826
  function momentsDifference(base, other) {
1772
1827
  var res;
1828
+ if (!(base.isValid() && other.isValid())) {
1829
+ return {milliseconds: 0, months: 0};
1830
+ }
1831
+
1773
1832
  other = cloneWithOffset(other, base);
1774
1833
  if (base.isBefore(other)) {
1775
1834
  res = positiveMomentsDifference(base, other);
@@ -1782,6 +1841,7 @@
1782
1841
  return res;
1783
1842
  }
1784
1843
 
1844
+ // TODO: remove 'name' arg after deprecation is removed
1785
1845
  function createAdder(direction, name) {
1786
1846
  return function (val, period) {
1787
1847
  var dur, tmp;
@@ -1802,6 +1862,12 @@
1802
1862
  var milliseconds = duration._milliseconds,
1803
1863
  days = duration._days,
1804
1864
  months = duration._months;
1865
+
1866
+ if (!mom.isValid()) {
1867
+ // No op
1868
+ return;
1869
+ }
1870
+
1805
1871
  updateOffset = updateOffset == null ? true : updateOffset;
1806
1872
 
1807
1873
  if (milliseconds) {
@@ -1833,7 +1899,10 @@
1833
1899
  diff < 1 ? 'sameDay' :
1834
1900
  diff < 2 ? 'nextDay' :
1835
1901
  diff < 7 ? 'nextWeek' : 'sameElse';
1836
- return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
1902
+
1903
+ var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]);
1904
+
1905
+ return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
1837
1906
  }
1838
1907
 
1839
1908
  function clone () {
@@ -1841,26 +1910,28 @@
1841
1910
  }
1842
1911
 
1843
1912
  function isAfter (input, units) {
1844
- var inputMs;
1845
- units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
1913
+ var localInput = isMoment(input) ? input : local__createLocal(input);
1914
+ if (!(this.isValid() && localInput.isValid())) {
1915
+ return false;
1916
+ }
1917
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
1846
1918
  if (units === 'millisecond') {
1847
- input = isMoment(input) ? input : local__createLocal(input);
1848
- return +this > +input;
1919
+ return +this > +localInput;
1849
1920
  } else {
1850
- inputMs = isMoment(input) ? +input : +local__createLocal(input);
1851
- return inputMs < +this.clone().startOf(units);
1921
+ return +localInput < +this.clone().startOf(units);
1852
1922
  }
1853
1923
  }
1854
1924
 
1855
1925
  function isBefore (input, units) {
1856
- var inputMs;
1857
- units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
1926
+ var localInput = isMoment(input) ? input : local__createLocal(input);
1927
+ if (!(this.isValid() && localInput.isValid())) {
1928
+ return false;
1929
+ }
1930
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
1858
1931
  if (units === 'millisecond') {
1859
- input = isMoment(input) ? input : local__createLocal(input);
1860
- return +this < +input;
1932
+ return +this < +localInput;
1861
1933
  } else {
1862
- inputMs = isMoment(input) ? +input : +local__createLocal(input);
1863
- return +this.clone().endOf(units) < inputMs;
1934
+ return +this.clone().endOf(units) < +localInput;
1864
1935
  }
1865
1936
  }
1866
1937
 
@@ -1869,22 +1940,45 @@
1869
1940
  }
1870
1941
 
1871
1942
  function isSame (input, units) {
1872
- var inputMs;
1943
+ var localInput = isMoment(input) ? input : local__createLocal(input),
1944
+ inputMs;
1945
+ if (!(this.isValid() && localInput.isValid())) {
1946
+ return false;
1947
+ }
1873
1948
  units = normalizeUnits(units || 'millisecond');
1874
1949
  if (units === 'millisecond') {
1875
- input = isMoment(input) ? input : local__createLocal(input);
1876
- return +this === +input;
1950
+ return +this === +localInput;
1877
1951
  } else {
1878
- inputMs = +local__createLocal(input);
1952
+ inputMs = +localInput;
1879
1953
  return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
1880
1954
  }
1881
1955
  }
1882
1956
 
1957
+ function isSameOrAfter (input, units) {
1958
+ return this.isSame(input, units) || this.isAfter(input,units);
1959
+ }
1960
+
1961
+ function isSameOrBefore (input, units) {
1962
+ return this.isSame(input, units) || this.isBefore(input,units);
1963
+ }
1964
+
1883
1965
  function diff (input, units, asFloat) {
1884
- var that = cloneWithOffset(input, this),
1885
- zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
1966
+ var that,
1967
+ zoneDelta,
1886
1968
  delta, output;
1887
1969
 
1970
+ if (!this.isValid()) {
1971
+ return NaN;
1972
+ }
1973
+
1974
+ that = cloneWithOffset(input, this);
1975
+
1976
+ if (!that.isValid()) {
1977
+ return NaN;
1978
+ }
1979
+
1980
+ zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
1981
+
1888
1982
  units = normalizeUnits(units);
1889
1983
 
1890
1984
  if (units === 'year' || units === 'month' || units === 'quarter') {
@@ -1935,7 +2029,7 @@
1935
2029
  function moment_format__toISOString () {
1936
2030
  var m = this.clone().utc();
1937
2031
  if (0 < m.year() && m.year() <= 9999) {
1938
- if ('function' === typeof Date.prototype.toISOString) {
2032
+ if (isFunction(Date.prototype.toISOString)) {
1939
2033
  // native implementation is ~50x faster, use it when we can
1940
2034
  return this.toDate().toISOString();
1941
2035
  } else {
@@ -1952,10 +2046,13 @@
1952
2046
  }
1953
2047
 
1954
2048
  function from (time, withoutSuffix) {
1955
- if (!this.isValid()) {
2049
+ if (this.isValid() &&
2050
+ ((isMoment(time) && time.isValid()) ||
2051
+ local__createLocal(time).isValid())) {
2052
+ return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2053
+ } else {
1956
2054
  return this.localeData().invalidDate();
1957
2055
  }
1958
- return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
1959
2056
  }
1960
2057
 
1961
2058
  function fromNow (withoutSuffix) {
@@ -1963,16 +2060,22 @@
1963
2060
  }
1964
2061
 
1965
2062
  function to (time, withoutSuffix) {
1966
- if (!this.isValid()) {
2063
+ if (this.isValid() &&
2064
+ ((isMoment(time) && time.isValid()) ||
2065
+ local__createLocal(time).isValid())) {
2066
+ return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
2067
+ } else {
1967
2068
  return this.localeData().invalidDate();
1968
2069
  }
1969
- return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
1970
2070
  }
1971
2071
 
1972
2072
  function toNow (withoutSuffix) {
1973
2073
  return this.to(local__createLocal(), withoutSuffix);
1974
2074
  }
1975
2075
 
2076
+ // If passed a locale key, it will set the locale for this
2077
+ // instance. Otherwise, it will return the locale configuration
2078
+ // variables for this instance.
1976
2079
  function locale (key) {
1977
2080
  var newLocaleData;
1978
2081
 
@@ -2083,6 +2186,11 @@
2083
2186
  };
2084
2187
  }
2085
2188
 
2189
+ function toJSON () {
2190
+ // JSON.stringify(new Date(NaN)) === 'null'
2191
+ return this.isValid() ? this.toISOString() : 'null';
2192
+ }
2193
+
2086
2194
  function moment_valid__isValid () {
2087
2195
  return valid__isValid(this);
2088
2196
  }
@@ -2095,6 +2203,18 @@
2095
2203
  return getParsingFlags(this).overflow;
2096
2204
  }
2097
2205
 
2206
+ function creationData() {
2207
+ return {
2208
+ input: this._i,
2209
+ format: this._f,
2210
+ locale: this._locale,
2211
+ isUTC: this._isUTC,
2212
+ strict: this._strict
2213
+ };
2214
+ }
2215
+
2216
+ // FORMATTING
2217
+
2098
2218
  addFormatToken(0, ['gg', 2], 0, function () {
2099
2219
  return this.weekYear() % 100;
2100
2220
  });
@@ -2136,22 +2256,20 @@
2136
2256
  week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
2137
2257
  });
2138
2258
 
2139
- // HELPERS
2140
-
2141
- function weeksInYear(year, dow, doy) {
2142
- return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;
2143
- }
2144
-
2145
2259
  // MOMENTS
2146
2260
 
2147
2261
  function getSetWeekYear (input) {
2148
- var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2149
- return input == null ? year : this.add((input - year), 'y');
2262
+ return getSetWeekYearHelper.call(this,
2263
+ input,
2264
+ this.week(),
2265
+ this.weekday(),
2266
+ this.localeData()._week.dow,
2267
+ this.localeData()._week.doy);
2150
2268
  }
2151
2269
 
2152
2270
  function getSetISOWeekYear (input) {
2153
- var year = weekOfYear(this, 1, 4).year;
2154
- return input == null ? year : this.add((input - year), 'y');
2271
+ return getSetWeekYearHelper.call(this,
2272
+ input, this.isoWeek(), this.isoWeekday(), 1, 4);
2155
2273
  }
2156
2274
 
2157
2275
  function getISOWeeksInYear () {
@@ -2163,7 +2281,33 @@
2163
2281
  return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2164
2282
  }
2165
2283
 
2166
- addFormatToken('Q', 0, 0, 'quarter');
2284
+ function getSetWeekYearHelper(input, week, weekday, dow, doy) {
2285
+ var weeksTarget;
2286
+ if (input == null) {
2287
+ return weekOfYear(this, dow, doy).year;
2288
+ } else {
2289
+ weeksTarget = weeksInYear(input, dow, doy);
2290
+ if (week > weeksTarget) {
2291
+ week = weeksTarget;
2292
+ }
2293
+ return setWeekAll.call(this, input, week, weekday, dow, doy);
2294
+ }
2295
+ }
2296
+
2297
+ function setWeekAll(weekYear, week, weekday, dow, doy) {
2298
+ var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
2299
+ date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
2300
+
2301
+ // console.log("got", weekYear, week, weekday, "set", date.toISOString());
2302
+ this.year(date.getUTCFullYear());
2303
+ this.month(date.getUTCMonth());
2304
+ this.date(date.getUTCDate());
2305
+ return this;
2306
+ }
2307
+
2308
+ // FORMATTING
2309
+
2310
+ addFormatToken('Q', 0, 'Qo', 'quarter');
2167
2311
 
2168
2312
  // ALIASES
2169
2313
 
@@ -2182,6 +2326,62 @@
2182
2326
  return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
2183
2327
  }
2184
2328
 
2329
+ // FORMATTING
2330
+
2331
+ addFormatToken('w', ['ww', 2], 'wo', 'week');
2332
+ addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
2333
+
2334
+ // ALIASES
2335
+
2336
+ addUnitAlias('week', 'w');
2337
+ addUnitAlias('isoWeek', 'W');
2338
+
2339
+ // PARSING
2340
+
2341
+ addRegexToken('w', match1to2);
2342
+ addRegexToken('ww', match1to2, match2);
2343
+ addRegexToken('W', match1to2);
2344
+ addRegexToken('WW', match1to2, match2);
2345
+
2346
+ addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
2347
+ week[token.substr(0, 1)] = toInt(input);
2348
+ });
2349
+
2350
+ // HELPERS
2351
+
2352
+ // LOCALES
2353
+
2354
+ function localeWeek (mom) {
2355
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
2356
+ }
2357
+
2358
+ var defaultLocaleWeek = {
2359
+ dow : 0, // Sunday is the first day of the week.
2360
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
2361
+ };
2362
+
2363
+ function localeFirstDayOfWeek () {
2364
+ return this._week.dow;
2365
+ }
2366
+
2367
+ function localeFirstDayOfYear () {
2368
+ return this._week.doy;
2369
+ }
2370
+
2371
+ // MOMENTS
2372
+
2373
+ function getSetWeek (input) {
2374
+ var week = this.localeData().week(this);
2375
+ return input == null ? week : this.add((input - week) * 7, 'd');
2376
+ }
2377
+
2378
+ function getSetISOWeek (input) {
2379
+ var week = weekOfYear(this, 1, 4).week;
2380
+ return input == null ? week : this.add((input - week) * 7, 'd');
2381
+ }
2382
+
2383
+ // FORMATTING
2384
+
2185
2385
  addFormatToken('D', ['DD', 2], 'Do', 'date');
2186
2386
 
2187
2387
  // ALIASES
@@ -2205,6 +2405,8 @@
2205
2405
 
2206
2406
  var getSetDayOfMonth = makeGetSet('Date', true);
2207
2407
 
2408
+ // FORMATTING
2409
+
2208
2410
  addFormatToken('d', 0, 'do', 'day');
2209
2411
 
2210
2412
  addFormatToken('dd', 0, 0, function (format) {
@@ -2237,8 +2439,8 @@
2237
2439
  addRegexToken('ddd', matchWord);
2238
2440
  addRegexToken('dddd', matchWord);
2239
2441
 
2240
- addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {
2241
- var weekday = config._locale.weekdaysParse(input);
2442
+ addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
2443
+ var weekday = config._locale.weekdaysParse(input, token, config._strict);
2242
2444
  // if we didn't get a weekday name, mark the date as invalid
2243
2445
  if (weekday != null) {
2244
2446
  week.d = weekday;
@@ -2273,8 +2475,9 @@
2273
2475
  // LOCALES
2274
2476
 
2275
2477
  var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
2276
- function localeWeekdays (m) {
2277
- return this._weekdays[m.day()];
2478
+ function localeWeekdays (m, format) {
2479
+ return isArray(this._weekdays) ? this._weekdays[m.day()] :
2480
+ this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
2278
2481
  }
2279
2482
 
2280
2483
  var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
@@ -2287,20 +2490,37 @@
2287
2490
  return this._weekdaysMin[m.day()];
2288
2491
  }
2289
2492
 
2290
- function localeWeekdaysParse (weekdayName) {
2493
+ function localeWeekdaysParse (weekdayName, format, strict) {
2291
2494
  var i, mom, regex;
2292
2495
 
2293
- this._weekdaysParse = this._weekdaysParse || [];
2496
+ if (!this._weekdaysParse) {
2497
+ this._weekdaysParse = [];
2498
+ this._minWeekdaysParse = [];
2499
+ this._shortWeekdaysParse = [];
2500
+ this._fullWeekdaysParse = [];
2501
+ }
2294
2502
 
2295
2503
  for (i = 0; i < 7; i++) {
2296
2504
  // make the regex if we don't have it already
2505
+
2506
+ mom = local__createLocal([2000, 1]).day(i);
2507
+ if (strict && !this._fullWeekdaysParse[i]) {
2508
+ this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
2509
+ this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
2510
+ this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
2511
+ }
2297
2512
  if (!this._weekdaysParse[i]) {
2298
- mom = local__createLocal([2000, 1]).day(i);
2299
2513
  regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
2300
2514
  this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
2301
2515
  }
2302
2516
  // test the regex
2303
- if (this._weekdaysParse[i].test(weekdayName)) {
2517
+ if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
2518
+ return i;
2519
+ } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
2520
+ return i;
2521
+ } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
2522
+ return i;
2523
+ } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
2304
2524
  return i;
2305
2525
  }
2306
2526
  }
@@ -2309,6 +2529,9 @@
2309
2529
  // MOMENTS
2310
2530
 
2311
2531
  function getSetDayOfWeek (input) {
2532
+ if (!this.isValid()) {
2533
+ return input != null ? this : NaN;
2534
+ }
2312
2535
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2313
2536
  if (input != null) {
2314
2537
  input = parseWeekday(input, this.localeData());
@@ -2319,20 +2542,73 @@
2319
2542
  }
2320
2543
 
2321
2544
  function getSetLocaleDayOfWeek (input) {
2545
+ if (!this.isValid()) {
2546
+ return input != null ? this : NaN;
2547
+ }
2322
2548
  var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2323
2549
  return input == null ? weekday : this.add(input - weekday, 'd');
2324
2550
  }
2325
2551
 
2326
2552
  function getSetISODayOfWeek (input) {
2553
+ if (!this.isValid()) {
2554
+ return input != null ? this : NaN;
2555
+ }
2327
2556
  // behaves the same as moment#day except
2328
2557
  // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
2329
2558
  // as a setter, sunday should belong to the previous week.
2330
2559
  return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
2331
2560
  }
2332
2561
 
2333
- addFormatToken('H', ['HH', 2], 0, 'hour');
2334
- addFormatToken('h', ['hh', 2], 0, function () {
2562
+ // FORMATTING
2563
+
2564
+ addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
2565
+
2566
+ // ALIASES
2567
+
2568
+ addUnitAlias('dayOfYear', 'DDD');
2569
+
2570
+ // PARSING
2571
+
2572
+ addRegexToken('DDD', match1to3);
2573
+ addRegexToken('DDDD', match3);
2574
+ addParseToken(['DDD', 'DDDD'], function (input, array, config) {
2575
+ config._dayOfYear = toInt(input);
2576
+ });
2577
+
2578
+ // HELPERS
2579
+
2580
+ // MOMENTS
2581
+
2582
+ function getSetDayOfYear (input) {
2583
+ var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
2584
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2585
+ }
2586
+
2587
+ // FORMATTING
2588
+
2589
+ function hFormat() {
2335
2590
  return this.hours() % 12 || 12;
2591
+ }
2592
+
2593
+ addFormatToken('H', ['HH', 2], 0, 'hour');
2594
+ addFormatToken('h', ['hh', 2], 0, hFormat);
2595
+
2596
+ addFormatToken('hmm', 0, 0, function () {
2597
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
2598
+ });
2599
+
2600
+ addFormatToken('hmmss', 0, 0, function () {
2601
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
2602
+ zeroFill(this.seconds(), 2);
2603
+ });
2604
+
2605
+ addFormatToken('Hmm', 0, 0, function () {
2606
+ return '' + this.hours() + zeroFill(this.minutes(), 2);
2607
+ });
2608
+
2609
+ addFormatToken('Hmmss', 0, 0, function () {
2610
+ return '' + this.hours() + zeroFill(this.minutes(), 2) +
2611
+ zeroFill(this.seconds(), 2);
2336
2612
  });
2337
2613
 
2338
2614
  function meridiem (token, lowercase) {
@@ -2361,6 +2637,11 @@
2361
2637
  addRegexToken('HH', match1to2, match2);
2362
2638
  addRegexToken('hh', match1to2, match2);
2363
2639
 
2640
+ addRegexToken('hmm', match3to4);
2641
+ addRegexToken('hmmss', match5to6);
2642
+ addRegexToken('Hmm', match3to4);
2643
+ addRegexToken('Hmmss', match5to6);
2644
+
2364
2645
  addParseToken(['H', 'HH'], HOUR);
2365
2646
  addParseToken(['a', 'A'], function (input, array, config) {
2366
2647
  config._isPm = config._locale.isPM(input);
@@ -2370,6 +2651,32 @@
2370
2651
  array[HOUR] = toInt(input);
2371
2652
  getParsingFlags(config).bigHour = true;
2372
2653
  });
2654
+ addParseToken('hmm', function (input, array, config) {
2655
+ var pos = input.length - 2;
2656
+ array[HOUR] = toInt(input.substr(0, pos));
2657
+ array[MINUTE] = toInt(input.substr(pos));
2658
+ getParsingFlags(config).bigHour = true;
2659
+ });
2660
+ addParseToken('hmmss', function (input, array, config) {
2661
+ var pos1 = input.length - 4;
2662
+ var pos2 = input.length - 2;
2663
+ array[HOUR] = toInt(input.substr(0, pos1));
2664
+ array[MINUTE] = toInt(input.substr(pos1, 2));
2665
+ array[SECOND] = toInt(input.substr(pos2));
2666
+ getParsingFlags(config).bigHour = true;
2667
+ });
2668
+ addParseToken('Hmm', function (input, array, config) {
2669
+ var pos = input.length - 2;
2670
+ array[HOUR] = toInt(input.substr(0, pos));
2671
+ array[MINUTE] = toInt(input.substr(pos));
2672
+ });
2673
+ addParseToken('Hmmss', function (input, array, config) {
2674
+ var pos1 = input.length - 4;
2675
+ var pos2 = input.length - 2;
2676
+ array[HOUR] = toInt(input.substr(0, pos1));
2677
+ array[MINUTE] = toInt(input.substr(pos1, 2));
2678
+ array[SECOND] = toInt(input.substr(pos2));
2679
+ });
2373
2680
 
2374
2681
  // LOCALES
2375
2682
 
@@ -2397,6 +2704,8 @@
2397
2704
  // this rule.
2398
2705
  var getSetHour = makeGetSet('Hours', true);
2399
2706
 
2707
+ // FORMATTING
2708
+
2400
2709
  addFormatToken('m', ['mm', 2], 0, 'minute');
2401
2710
 
2402
2711
  // ALIASES
@@ -2413,6 +2722,8 @@
2413
2722
 
2414
2723
  var getSetMinute = makeGetSet('Minutes', false);
2415
2724
 
2725
+ // FORMATTING
2726
+
2416
2727
  addFormatToken('s', ['ss', 2], 0, 'second');
2417
2728
 
2418
2729
  // ALIASES
@@ -2429,6 +2740,8 @@
2429
2740
 
2430
2741
  var getSetSecond = makeGetSet('Seconds', false);
2431
2742
 
2743
+ // FORMATTING
2744
+
2432
2745
  addFormatToken('S', 0, 0, function () {
2433
2746
  return ~~(this.millisecond() / 100);
2434
2747
  });
@@ -2484,6 +2797,8 @@
2484
2797
 
2485
2798
  var getSetMillisecond = makeGetSet('Milliseconds', false);
2486
2799
 
2800
+ // FORMATTING
2801
+
2487
2802
  addFormatToken('z', 0, 0, 'zoneAbbr');
2488
2803
  addFormatToken('zz', 0, 0, 'zoneName');
2489
2804
 
@@ -2499,40 +2814,43 @@
2499
2814
 
2500
2815
  var momentPrototype__proto = Moment.prototype;
2501
2816
 
2502
- momentPrototype__proto.add = add_subtract__add;
2503
- momentPrototype__proto.calendar = moment_calendar__calendar;
2504
- momentPrototype__proto.clone = clone;
2505
- momentPrototype__proto.diff = diff;
2506
- momentPrototype__proto.endOf = endOf;
2507
- momentPrototype__proto.format = format;
2508
- momentPrototype__proto.from = from;
2509
- momentPrototype__proto.fromNow = fromNow;
2510
- momentPrototype__proto.to = to;
2511
- momentPrototype__proto.toNow = toNow;
2512
- momentPrototype__proto.get = getSet;
2513
- momentPrototype__proto.invalidAt = invalidAt;
2514
- momentPrototype__proto.isAfter = isAfter;
2515
- momentPrototype__proto.isBefore = isBefore;
2516
- momentPrototype__proto.isBetween = isBetween;
2517
- momentPrototype__proto.isSame = isSame;
2518
- momentPrototype__proto.isValid = moment_valid__isValid;
2519
- momentPrototype__proto.lang = lang;
2520
- momentPrototype__proto.locale = locale;
2521
- momentPrototype__proto.localeData = localeData;
2522
- momentPrototype__proto.max = prototypeMax;
2523
- momentPrototype__proto.min = prototypeMin;
2524
- momentPrototype__proto.parsingFlags = parsingFlags;
2525
- momentPrototype__proto.set = getSet;
2526
- momentPrototype__proto.startOf = startOf;
2527
- momentPrototype__proto.subtract = add_subtract__subtract;
2528
- momentPrototype__proto.toArray = toArray;
2529
- momentPrototype__proto.toObject = toObject;
2530
- momentPrototype__proto.toDate = toDate;
2531
- momentPrototype__proto.toISOString = moment_format__toISOString;
2532
- momentPrototype__proto.toJSON = moment_format__toISOString;
2533
- momentPrototype__proto.toString = toString;
2534
- momentPrototype__proto.unix = unix;
2535
- momentPrototype__proto.valueOf = to_type__valueOf;
2817
+ momentPrototype__proto.add = add_subtract__add;
2818
+ momentPrototype__proto.calendar = moment_calendar__calendar;
2819
+ momentPrototype__proto.clone = clone;
2820
+ momentPrototype__proto.diff = diff;
2821
+ momentPrototype__proto.endOf = endOf;
2822
+ momentPrototype__proto.format = format;
2823
+ momentPrototype__proto.from = from;
2824
+ momentPrototype__proto.fromNow = fromNow;
2825
+ momentPrototype__proto.to = to;
2826
+ momentPrototype__proto.toNow = toNow;
2827
+ momentPrototype__proto.get = getSet;
2828
+ momentPrototype__proto.invalidAt = invalidAt;
2829
+ momentPrototype__proto.isAfter = isAfter;
2830
+ momentPrototype__proto.isBefore = isBefore;
2831
+ momentPrototype__proto.isBetween = isBetween;
2832
+ momentPrototype__proto.isSame = isSame;
2833
+ momentPrototype__proto.isSameOrAfter = isSameOrAfter;
2834
+ momentPrototype__proto.isSameOrBefore = isSameOrBefore;
2835
+ momentPrototype__proto.isValid = moment_valid__isValid;
2836
+ momentPrototype__proto.lang = lang;
2837
+ momentPrototype__proto.locale = locale;
2838
+ momentPrototype__proto.localeData = localeData;
2839
+ momentPrototype__proto.max = prototypeMax;
2840
+ momentPrototype__proto.min = prototypeMin;
2841
+ momentPrototype__proto.parsingFlags = parsingFlags;
2842
+ momentPrototype__proto.set = getSet;
2843
+ momentPrototype__proto.startOf = startOf;
2844
+ momentPrototype__proto.subtract = add_subtract__subtract;
2845
+ momentPrototype__proto.toArray = toArray;
2846
+ momentPrototype__proto.toObject = toObject;
2847
+ momentPrototype__proto.toDate = toDate;
2848
+ momentPrototype__proto.toISOString = moment_format__toISOString;
2849
+ momentPrototype__proto.toJSON = toJSON;
2850
+ momentPrototype__proto.toString = toString;
2851
+ momentPrototype__proto.unix = unix;
2852
+ momentPrototype__proto.valueOf = to_type__valueOf;
2853
+ momentPrototype__proto.creationData = creationData;
2536
2854
 
2537
2855
  // Year
2538
2856
  momentPrototype__proto.year = getSetYear;
@@ -2618,7 +2936,7 @@
2618
2936
 
2619
2937
  function locale_calendar__calendar (key, mom, now) {
2620
2938
  var output = this._calendar[key];
2621
- return typeof output === 'function' ? output.call(mom, now) : output;
2939
+ return isFunction(output) ? output.call(mom, now) : output;
2622
2940
  }
2623
2941
 
2624
2942
  var defaultLongDateFormat = {
@@ -2680,21 +2998,21 @@
2680
2998
 
2681
2999
  function relative__relativeTime (number, withoutSuffix, string, isFuture) {
2682
3000
  var output = this._relativeTime[string];
2683
- return (typeof output === 'function') ?
3001
+ return (isFunction(output)) ?
2684
3002
  output(number, withoutSuffix, string, isFuture) :
2685
3003
  output.replace(/%d/i, number);
2686
3004
  }
2687
3005
 
2688
3006
  function pastFuture (diff, output) {
2689
3007
  var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
2690
- return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
3008
+ return isFunction(format) ? format(output) : format.replace(/%s/i, output);
2691
3009
  }
2692
3010
 
2693
3011
  function locale_set__set (config) {
2694
3012
  var prop, i;
2695
3013
  for (i in config) {
2696
3014
  prop = config[i];
2697
- if (typeof prop === 'function') {
3015
+ if (isFunction(prop)) {
2698
3016
  this[i] = prop;
2699
3017
  } else {
2700
3018
  this['_' + i] = prop;
@@ -2797,6 +3115,9 @@
2797
3115
  }
2798
3116
 
2799
3117
  locale_locales__getSetGlobalLocale('en', {
3118
+ monthsParse : [/^jan/i, /^feb/i, /^mar/i, /^apr/i, /^may/i, /^jun/i, /^jul/i, /^aug/i, /^sep/i, /^oct/i, /^nov/i, /^dec/i],
3119
+ longMonthsParse : [/^january$/i, /^february$/i, /^march$/i, /^april$/i, /^may$/i, /^june$/i, /^july$/i, /^august$/i, /^september$/i, /^october$/i, /^november$/i, /^december$/i],
3120
+ shortMonthsParse : [/^jan$/i, /^feb$/i, /^mar$/i, /^apr$/i, /^may$/i, /^jun$/i, /^jul$/i, /^aug/i, /^sept?$/i, /^oct$/i, /^nov$/i, /^dec$/i],
2800
3121
  ordinalParse: /\d{1,2}(th|st|nd|rd)/,
2801
3122
  ordinal : function (number) {
2802
3123
  var b = number % 10,
@@ -3016,15 +3337,15 @@
3016
3337
  var years = round(duration.as('y'));
3017
3338
 
3018
3339
  var a = seconds < thresholds.s && ['s', seconds] ||
3019
- minutes === 1 && ['m'] ||
3340
+ minutes <= 1 && ['m'] ||
3020
3341
  minutes < thresholds.m && ['mm', minutes] ||
3021
- hours === 1 && ['h'] ||
3342
+ hours <= 1 && ['h'] ||
3022
3343
  hours < thresholds.h && ['hh', hours] ||
3023
- days === 1 && ['d'] ||
3344
+ days <= 1 && ['d'] ||
3024
3345
  days < thresholds.d && ['dd', days] ||
3025
- months === 1 && ['M'] ||
3346
+ months <= 1 && ['M'] ||
3026
3347
  months < thresholds.M && ['MM', months] ||
3027
- years === 1 && ['y'] || ['yy', years];
3348
+ years <= 1 && ['y'] || ['yy', years];
3028
3349
 
3029
3350
  a[2] = withoutSuffix;
3030
3351
  a[3] = +posNegDuration > 0;
@@ -3145,6 +3466,8 @@
3145
3466
 
3146
3467
  // Side effect imports
3147
3468
 
3469
+ // FORMATTING
3470
+
3148
3471
  addFormatToken('X', 0, 0, 'unix');
3149
3472
  addFormatToken('x', 0, 0, 'valueOf');
3150
3473
 
@@ -3162,13 +3485,14 @@
3162
3485
  // Side effect imports
3163
3486
 
3164
3487
 
3165
- utils_hooks__hooks.version = '2.10.6';
3488
+ utils_hooks__hooks.version = '2.11.0';
3166
3489
 
3167
3490
  setHookCallback(local__createLocal);
3168
3491
 
3169
3492
  utils_hooks__hooks.fn = momentPrototype;
3170
3493
  utils_hooks__hooks.min = min;
3171
3494
  utils_hooks__hooks.max = max;
3495
+ utils_hooks__hooks.now = now;
3172
3496
  utils_hooks__hooks.utc = create_utc__createUTC;
3173
3497
  utils_hooks__hooks.unix = moment__createUnix;
3174
3498
  utils_hooks__hooks.months = lists__listMonths;
@@ -3187,9 +3511,10 @@
3187
3511
  utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;
3188
3512
  utils_hooks__hooks.normalizeUnits = normalizeUnits;
3189
3513
  utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
3514
+ utils_hooks__hooks.prototype = momentPrototype;
3190
3515
 
3191
3516
  var _moment = utils_hooks__hooks;
3192
3517
 
3193
3518
  return _moment;
3194
3519
 
3195
- }));
3520
+ }));