momentjs-rails 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/news.md +3 -0
  4. data/test/integration/navigation_test.rb +1 -1
  5. data/vendor/assets/javascripts/moment.js +560 -367
  6. data/vendor/assets/javascripts/moment/af.js +65 -0
  7. data/vendor/assets/javascripts/moment/ar-ma.js +3 -3
  8. data/vendor/assets/javascripts/moment/ar-sa.js +3 -3
  9. data/vendor/assets/javascripts/moment/ar.js +3 -3
  10. data/vendor/assets/javascripts/moment/az.js +3 -4
  11. data/vendor/assets/javascripts/moment/be.js +150 -0
  12. data/vendor/assets/javascripts/moment/bg.js +3 -3
  13. data/vendor/assets/javascripts/moment/bn.js +4 -4
  14. data/vendor/assets/javascripts/moment/bo.js +103 -0
  15. data/vendor/assets/javascripts/moment/br.js +3 -3
  16. data/vendor/assets/javascripts/moment/bs.js +5 -6
  17. data/vendor/assets/javascripts/moment/ca.js +3 -3
  18. data/vendor/assets/javascripts/moment/cs.js +3 -3
  19. data/vendor/assets/javascripts/moment/cv.js +3 -3
  20. data/vendor/assets/javascripts/moment/cy.js +3 -3
  21. data/vendor/assets/javascripts/moment/da.js +3 -3
  22. data/vendor/assets/javascripts/moment/de-at.js +3 -3
  23. data/vendor/assets/javascripts/moment/de.js +3 -3
  24. data/vendor/assets/javascripts/moment/el.js +4 -4
  25. data/vendor/assets/javascripts/moment/en-au.js +4 -4
  26. data/vendor/assets/javascripts/moment/en-ca.js +4 -4
  27. data/vendor/assets/javascripts/moment/en-gb.js +4 -4
  28. data/vendor/assets/javascripts/moment/eo.js +3 -3
  29. data/vendor/assets/javascripts/moment/es.js +3 -3
  30. data/vendor/assets/javascripts/moment/et.js +3 -3
  31. data/vendor/assets/javascripts/moment/eu.js +3 -3
  32. data/vendor/assets/javascripts/moment/fa.js +3 -3
  33. data/vendor/assets/javascripts/moment/fi.js +7 -5
  34. data/vendor/assets/javascripts/moment/fo.js +3 -3
  35. data/vendor/assets/javascripts/moment/fr-ca.js +3 -3
  36. data/vendor/assets/javascripts/moment/fr.js +3 -3
  37. data/vendor/assets/javascripts/moment/gl.js +3 -3
  38. data/vendor/assets/javascripts/moment/he.js +3 -3
  39. data/vendor/assets/javascripts/moment/hi.js +3 -3
  40. data/vendor/assets/javascripts/moment/hr.js +3 -4
  41. data/vendor/assets/javascripts/moment/hu.js +3 -3
  42. data/vendor/assets/javascripts/moment/hy-am.js +3 -4
  43. data/vendor/assets/javascripts/moment/id.js +3 -3
  44. data/vendor/assets/javascripts/moment/is.js +3 -3
  45. data/vendor/assets/javascripts/moment/it.js +3 -3
  46. data/vendor/assets/javascripts/moment/ja.js +3 -3
  47. data/vendor/assets/javascripts/moment/ka.js +3 -4
  48. data/vendor/assets/javascripts/moment/km.js +3 -3
  49. data/vendor/assets/javascripts/moment/ko.js +4 -4
  50. data/vendor/assets/javascripts/moment/lb.js +29 -52
  51. data/vendor/assets/javascripts/moment/lt.js +4 -4
  52. data/vendor/assets/javascripts/moment/lv.js +3 -3
  53. data/vendor/assets/javascripts/moment/mk.js +3 -3
  54. data/vendor/assets/javascripts/moment/ml.js +3 -3
  55. data/vendor/assets/javascripts/moment/mr.js +3 -3
  56. data/vendor/assets/javascripts/moment/ms-my.js +3 -3
  57. data/vendor/assets/javascripts/moment/my.js +88 -0
  58. data/vendor/assets/javascripts/moment/nb.js +3 -3
  59. data/vendor/assets/javascripts/moment/ne.js +3 -3
  60. data/vendor/assets/javascripts/moment/nl.js +3 -3
  61. data/vendor/assets/javascripts/moment/nn.js +3 -3
  62. data/vendor/assets/javascripts/moment/pl.js +3 -3
  63. data/vendor/assets/javascripts/moment/pt-br.js +3 -3
  64. data/vendor/assets/javascripts/moment/pt.js +3 -3
  65. data/vendor/assets/javascripts/moment/ro.js +9 -9
  66. data/vendor/assets/javascripts/moment/ru.js +3 -3
  67. data/vendor/assets/javascripts/moment/sk.js +3 -3
  68. data/vendor/assets/javascripts/moment/sl.js +3 -3
  69. data/vendor/assets/javascripts/moment/sq.js +3 -3
  70. data/vendor/assets/javascripts/moment/sr-cyrl.js +3 -4
  71. data/vendor/assets/javascripts/moment/sr.js +3 -4
  72. data/vendor/assets/javascripts/moment/sv.js +4 -4
  73. data/vendor/assets/javascripts/moment/ta.js +9 -9
  74. data/vendor/assets/javascripts/moment/th.js +3 -3
  75. data/vendor/assets/javascripts/moment/tl-ph.js +3 -3
  76. data/vendor/assets/javascripts/moment/tr.js +3 -4
  77. data/vendor/assets/javascripts/moment/tzm-latn.js +3 -3
  78. data/vendor/assets/javascripts/moment/tzm.js +3 -3
  79. data/vendor/assets/javascripts/moment/uk.js +3 -3
  80. data/vendor/assets/javascripts/moment/uz.js +3 -3
  81. data/vendor/assets/javascripts/moment/vi.js +3 -3
  82. data/vendor/assets/javascripts/moment/zh-cn.js +3 -3
  83. data/vendor/assets/javascripts/moment/zh-tw.js +3 -3
  84. metadata +13 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ebd1de8ebaf16234de4066959689ed14457b0f6
4
- data.tar.gz: 2b64b2b657ae712cae91470d6f144cdced41914f
3
+ metadata.gz: 0426cbbc4eff925ef47d88fb7f6e3ee93068e4b5
4
+ data.tar.gz: 823543eba7d87c03112e982d1a8569672e0dfac9
5
5
  SHA512:
6
- metadata.gz: 5990cdc4cd0195af98b7c2d29e66b464305fcb30f8a72c836509cbee35e40ef660b817a3b410490d28d6193c9e9c0ac78d79df0aabdfec21e1da91e07712f16c
7
- data.tar.gz: deea01a7ae4423921f9259523283514bf2e29ec64702e56668fabf51fc0037b4331475fbfd96481a7b2f22e19753def05c244669d27976efaf4d218d5e78c446
6
+ metadata.gz: 725bd561c1623c88bdeea097574d0f3c5d3a17b1334e52f0e138dab411d09044edca7e3f3c754952b3c4c2bdcd6dc46365665648baa3ba5817b12e6c383c93f3
7
+ data.tar.gz: 47edf3fd8d218cd64e4560ed91ef0ae48064cea1b81acd47ae3185ba63ec643d397208904e8fafeae6917d9f9dc83aa3c533b502ec0b29b49e2ab61de2159b13
data/README.md CHANGED
@@ -24,7 +24,7 @@ If you want to include a localization file, also add the following directive:
24
24
 
25
25
  ## Versioning
26
26
 
27
- momentjs-rails 2.7.0 == Moment.js 2.7.0
27
+ momentjs-rails 2.8.0 == Moment.js 2.8.0
28
28
 
29
29
  Every attempt is made to mirror the currently shipping Momentum.js version number wherever possible.
30
30
  The major, minor, and patch version numbers will always represent the Momentum.js version. Should a gem
data/news.md CHANGED
@@ -1,3 +1,6 @@
1
+ ### Version 2.8.0 (2014-08-06)
2
+ - Updated to Moment.js to 2.8.0
3
+
1
4
  ### Version 2.7.0 (2014-06-13)
2
5
  - Updated to Moment.js to 2.7.0
3
6
 
@@ -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(/VERSION = "2\.5\.1"/, @response.body)
11
+ assert_match(/VERSION = "2\.8\.0"/, @response.body)
12
12
  end
13
13
 
14
14
  test 'can access momentjs translation' do
@@ -1,17 +1,16 @@
1
1
  //! moment.js
2
- //! version : 2.7.0
2
+ //! version : 2.8.0
3
3
  //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4
4
  //! license : MIT
5
5
  //! momentjs.com
6
6
 
7
7
  (function (undefined) {
8
-
9
8
  /************************************
10
9
  Constants
11
10
  ************************************/
12
11
 
13
12
  var moment,
14
- VERSION = "2.7.0",
13
+ VERSION = '2.8.0',
15
14
  // the global-scope this is NOT the global object in Node.js
16
15
  globalScope = typeof global !== 'undefined' ? global : this,
17
16
  oldGlobalMoment,
@@ -26,22 +25,11 @@
26
25
  SECOND = 5,
27
26
  MILLISECOND = 6,
28
27
 
29
- // internal storage for language config files
30
- languages = {},
28
+ // internal storage for locale config files
29
+ locales = {},
31
30
 
32
- // moment internal properties
33
- momentProperties = {
34
- _isAMomentObject: null,
35
- _i : null,
36
- _f : null,
37
- _l : null,
38
- _strict : null,
39
- _tzm : null,
40
- _isUTC : null,
41
- _offset : null, // optional. Combine with _isUTC
42
- _pf : null,
43
- _lang : null // optional
44
- },
31
+ // extra moment internal properties (plugins register props here)
32
+ momentProperties = [],
45
33
 
46
34
  // check for nodeJS
47
35
  hasModule = (typeof module !== 'undefined' && module.exports),
@@ -147,12 +135,11 @@
147
135
 
148
136
  // default relative time thresholds
149
137
  relativeTimeThresholds = {
150
- s: 45, //seconds to minutes
151
- m: 45, //minutes to hours
152
- h: 22, //hours to days
153
- dd: 25, //days to month (month == 1)
154
- dm: 45, //days to months (months > 1)
155
- dy: 345 //days to year
138
+ s: 45, // seconds to minute
139
+ m: 45, // minutes to hour
140
+ h: 22, // hours to day
141
+ d: 26, // days to month
142
+ M: 11 // months to year
156
143
  },
157
144
 
158
145
  // tokens to ordinalize and pad
@@ -164,10 +151,10 @@
164
151
  return this.month() + 1;
165
152
  },
166
153
  MMM : function (format) {
167
- return this.lang().monthsShort(this, format);
154
+ return this.localeData().monthsShort(this, format);
168
155
  },
169
156
  MMMM : function (format) {
170
- return this.lang().months(this, format);
157
+ return this.localeData().months(this, format);
171
158
  },
172
159
  D : function () {
173
160
  return this.date();
@@ -179,13 +166,13 @@
179
166
  return this.day();
180
167
  },
181
168
  dd : function (format) {
182
- return this.lang().weekdaysMin(this, format);
169
+ return this.localeData().weekdaysMin(this, format);
183
170
  },
184
171
  ddd : function (format) {
185
- return this.lang().weekdaysShort(this, format);
172
+ return this.localeData().weekdaysShort(this, format);
186
173
  },
187
174
  dddd : function (format) {
188
- return this.lang().weekdays(this, format);
175
+ return this.localeData().weekdays(this, format);
189
176
  },
190
177
  w : function () {
191
178
  return this.week();
@@ -231,10 +218,10 @@
231
218
  return this.isoWeekday();
232
219
  },
233
220
  a : function () {
234
- return this.lang().meridiem(this.hours(), this.minutes(), true);
221
+ return this.localeData().meridiem(this.hours(), this.minutes(), true);
235
222
  },
236
223
  A : function () {
237
- return this.lang().meridiem(this.hours(), this.minutes(), false);
224
+ return this.localeData().meridiem(this.hours(), this.minutes(), false);
238
225
  },
239
226
  H : function () {
240
227
  return this.hours();
@@ -262,19 +249,19 @@
262
249
  },
263
250
  Z : function () {
264
251
  var a = -this.zone(),
265
- b = "+";
252
+ b = '+';
266
253
  if (a < 0) {
267
254
  a = -a;
268
- b = "-";
255
+ b = '-';
269
256
  }
270
- return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
257
+ return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
271
258
  },
272
259
  ZZ : function () {
273
260
  var a = -this.zone(),
274
- b = "+";
261
+ b = '+';
275
262
  if (a < 0) {
276
263
  a = -a;
277
- b = "-";
264
+ b = '-';
278
265
  }
279
266
  return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
280
267
  },
@@ -292,6 +279,8 @@
292
279
  }
293
280
  },
294
281
 
282
+ deprecations = {},
283
+
295
284
  lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
296
285
 
297
286
  // Pick the first defined of two or three arguments. dfl comes from
@@ -300,7 +289,7 @@
300
289
  switch (arguments.length) {
301
290
  case 2: return a != null ? a : b;
302
291
  case 3: return a != null ? a : b != null ? b : c;
303
- default: throw new Error("Implement me");
292
+ default: throw new Error('Implement me');
304
293
  }
305
294
  }
306
295
 
@@ -321,23 +310,31 @@
321
310
  };
322
311
  }
323
312
 
313
+ function printMsg(msg) {
314
+ if (moment.suppressDeprecationWarnings === false &&
315
+ typeof console !== 'undefined' && console.warn) {
316
+ console.warn("Deprecation warning: " + msg);
317
+ }
318
+ }
319
+
324
320
  function deprecate(msg, fn) {
325
321
  var firstTime = true;
326
- function printMsg() {
327
- if (moment.suppressDeprecationWarnings === false &&
328
- typeof console !== 'undefined' && console.warn) {
329
- console.warn("Deprecation warning: " + msg);
330
- }
331
- }
332
322
  return extend(function () {
333
323
  if (firstTime) {
334
- printMsg();
324
+ printMsg(msg);
335
325
  firstTime = false;
336
326
  }
337
327
  return fn.apply(this, arguments);
338
328
  }, fn);
339
329
  }
340
330
 
331
+ function deprecateSimple(name, msg) {
332
+ if (!deprecations[name]) {
333
+ printMsg(msg);
334
+ deprecations[name] = true;
335
+ }
336
+ }
337
+
341
338
  function padToken(func, count) {
342
339
  return function (a) {
343
340
  return leftZeroFill(func.call(this, a), count);
@@ -345,7 +342,7 @@
345
342
  }
346
343
  function ordinalizeToken(func, period) {
347
344
  return function (a) {
348
- return this.lang().ordinal(func.call(this, a), period);
345
+ return this.localeData().ordinal(func.call(this, a), period);
349
346
  };
350
347
  }
351
348
 
@@ -364,14 +361,16 @@
364
361
  Constructors
365
362
  ************************************/
366
363
 
367
- function Language() {
368
-
364
+ function Locale() {
369
365
  }
370
366
 
371
367
  // Moment prototype object
372
- function Moment(config) {
373
- checkOverflow(config);
374
- extend(this, config);
368
+ function Moment(config, skipOverflow) {
369
+ if (skipOverflow !== false) {
370
+ checkOverflow(config);
371
+ }
372
+ copyConfig(this, config);
373
+ this._d = new Date(+config._d);
375
374
  }
376
375
 
377
376
  // Duration Constructor
@@ -405,6 +404,8 @@
405
404
 
406
405
  this._data = {};
407
406
 
407
+ this._locale = moment.localeData();
408
+
408
409
  this._bubble();
409
410
  }
410
411
 
@@ -420,26 +421,62 @@
420
421
  }
421
422
  }
422
423
 
423
- if (b.hasOwnProperty("toString")) {
424
+ if (b.hasOwnProperty('toString')) {
424
425
  a.toString = b.toString;
425
426
  }
426
427
 
427
- if (b.hasOwnProperty("valueOf")) {
428
+ if (b.hasOwnProperty('valueOf')) {
428
429
  a.valueOf = b.valueOf;
429
430
  }
430
431
 
431
432
  return a;
432
433
  }
433
434
 
434
- function cloneMoment(m) {
435
- var result = {}, i;
436
- for (i in m) {
437
- if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
438
- result[i] = m[i];
435
+ function copyConfig(to, from) {
436
+ var i, prop, val;
437
+
438
+ if (typeof from._isAMomentObject !== 'undefined') {
439
+ to._isAMomentObject = from._isAMomentObject;
440
+ }
441
+ if (typeof from._i !== 'undefined') {
442
+ to._i = from._i;
443
+ }
444
+ if (typeof from._f !== 'undefined') {
445
+ to._f = from._f;
446
+ }
447
+ if (typeof from._l !== 'undefined') {
448
+ to._l = from._l;
449
+ }
450
+ if (typeof from._strict !== 'undefined') {
451
+ to._strict = from._strict;
452
+ }
453
+ if (typeof from._tzm !== 'undefined') {
454
+ to._tzm = from._tzm;
455
+ }
456
+ if (typeof from._isUTC !== 'undefined') {
457
+ to._isUTC = from._isUTC;
458
+ }
459
+ if (typeof from._offset !== 'undefined') {
460
+ to._offset = from._offset;
461
+ }
462
+ if (typeof from._pf !== 'undefined') {
463
+ to._pf = from._pf;
464
+ }
465
+ if (typeof from._locale !== 'undefined') {
466
+ to._locale = from._locale;
467
+ }
468
+
469
+ if (momentProperties.length > 0) {
470
+ for (i in momentProperties) {
471
+ prop = momentProperties[i];
472
+ val = from[prop];
473
+ if (typeof val !== 'undefined') {
474
+ to[prop] = val;
475
+ }
439
476
  }
440
477
  }
441
478
 
442
- return result;
479
+ return to;
443
480
  }
444
481
 
445
482
  function absRound(number) {
@@ -462,7 +499,51 @@
462
499
  return (sign ? (forceSign ? '+' : '') : '-') + output;
463
500
  }
464
501
 
465
- // helper function for _.addTime and _.subtractTime
502
+ function positiveMomentsDifference(base, other) {
503
+ var res = {milliseconds: 0, months: 0};
504
+
505
+ res.months = other.month() - base.month() +
506
+ (other.year() - base.year()) * 12;
507
+ if (base.clone().add(res.months, 'M').isAfter(other)) {
508
+ --res.months;
509
+ }
510
+
511
+ res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
512
+
513
+ return res;
514
+ }
515
+
516
+ function momentsDifference(base, other) {
517
+ var res;
518
+ other = makeAs(other, base);
519
+ if (base.isBefore(other)) {
520
+ res = positiveMomentsDifference(base, other);
521
+ } else {
522
+ res = positiveMomentsDifference(other, base);
523
+ res.milliseconds = -res.milliseconds;
524
+ res.months = -res.months;
525
+ }
526
+
527
+ return res;
528
+ }
529
+
530
+ // TODO: remove 'name' arg after deprecation is removed
531
+ function createAdder(direction, name) {
532
+ return function (val, period) {
533
+ var dur, tmp;
534
+ //invert the arguments, but complain about it
535
+ if (period !== null && !isNaN(+period)) {
536
+ deprecateSimple(name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period).");
537
+ tmp = val; val = period; period = tmp;
538
+ }
539
+
540
+ val = typeof val === 'string' ? +val : val;
541
+ dur = moment.duration(val, period);
542
+ addOrSubtractDurationFromMoment(this, dur, direction);
543
+ return this;
544
+ };
545
+ }
546
+
466
547
  function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
467
548
  var milliseconds = duration._milliseconds,
468
549
  days = duration._days,
@@ -489,8 +570,8 @@
489
570
  }
490
571
 
491
572
  function isDate(input) {
492
- return Object.prototype.toString.call(input) === '[object Date]' ||
493
- input instanceof Date;
573
+ return Object.prototype.toString.call(input) === '[object Date]' ||
574
+ input instanceof Date;
494
575
  }
495
576
 
496
577
  // compare two arrays, return the number of differences
@@ -550,7 +631,7 @@
550
631
 
551
632
  moment[field] = function (format, index) {
552
633
  var i, getter,
553
- method = moment.fn._lang[field],
634
+ method = moment._locale[field],
554
635
  results = [];
555
636
 
556
637
  if (typeof format === 'number') {
@@ -560,7 +641,7 @@
560
641
 
561
642
  getter = function (i) {
562
643
  var m = moment().utc().set(setter, i);
563
- return method.call(moment.fn._lang, m, format || '');
644
+ return method.call(moment._locale, m, format || '');
564
645
  };
565
646
 
566
647
  if (index != null) {
@@ -645,10 +726,50 @@
645
726
  return m._isValid;
646
727
  }
647
728
 
648
- function normalizeLanguage(key) {
729
+ function normalizeLocale(key) {
649
730
  return key ? key.toLowerCase().replace('_', '-') : key;
650
731
  }
651
732
 
733
+ // pick the locale from the array
734
+ // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
735
+ // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
736
+ function chooseLocale(names) {
737
+ var i = 0, j, next, locale, split;
738
+
739
+ while (i < names.length) {
740
+ split = normalizeLocale(names[i]).split('-');
741
+ j = split.length;
742
+ next = normalizeLocale(names[i + 1]);
743
+ next = next ? next.split('-') : null;
744
+ while (j > 0) {
745
+ locale = loadLocale(split.slice(0, j).join('-'));
746
+ if (locale) {
747
+ return locale;
748
+ }
749
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
750
+ //the next array item is better than a shallower substring of this one
751
+ break;
752
+ }
753
+ j--;
754
+ }
755
+ i++;
756
+ }
757
+ return null;
758
+ }
759
+
760
+ function loadLocale(name) {
761
+ var oldLocale = null;
762
+ if (!locales[name] && hasModule) {
763
+ try {
764
+ oldLocale = moment.locale();
765
+ require('./locale/' + name);
766
+ // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
767
+ moment.locale(oldLocale);
768
+ } catch (e) { }
769
+ }
770
+ return locales[name];
771
+ }
772
+
652
773
  // Return a moment from input, that is local/utc/zone equivalent to model.
653
774
  function makeAs(input, model) {
654
775
  return model._isUTC ? moment(input).zone(model._offset || 0) :
@@ -656,11 +777,11 @@
656
777
  }
657
778
 
658
779
  /************************************
659
- Languages
780
+ Locale
660
781
  ************************************/
661
782
 
662
783
 
663
- extend(Language.prototype, {
784
+ extend(Locale.prototype, {
664
785
 
665
786
  set : function (config) {
666
787
  var prop, i;
@@ -674,12 +795,12 @@
674
795
  }
675
796
  },
676
797
 
677
- _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
798
+ _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
678
799
  months : function (m) {
679
800
  return this._months[m.month()];
680
801
  },
681
802
 
682
- _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
803
+ _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
683
804
  monthsShort : function (m) {
684
805
  return this._monthsShort[m.month()];
685
806
  },
@@ -705,17 +826,17 @@
705
826
  }
706
827
  },
707
828
 
708
- _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
829
+ _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
709
830
  weekdays : function (m) {
710
831
  return this._weekdays[m.day()];
711
832
  },
712
833
 
713
- _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
834
+ _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
714
835
  weekdaysShort : function (m) {
715
836
  return this._weekdaysShort[m.day()];
716
837
  },
717
838
 
718
- _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
839
+ _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
719
840
  weekdaysMin : function (m) {
720
841
  return this._weekdaysMin[m.day()];
721
842
  },
@@ -742,11 +863,11 @@
742
863
  },
743
864
 
744
865
  _longDateFormat : {
745
- LT : "h:mm A",
746
- L : "MM/DD/YYYY",
747
- LL : "MMMM D YYYY",
748
- LLL : "MMMM D YYYY LT",
749
- LLLL : "dddd, MMMM D YYYY LT"
866
+ LT : 'h:mm A',
867
+ L : 'MM/DD/YYYY',
868
+ LL : 'MMMM D, YYYY',
869
+ LLL : 'MMMM D, YYYY LT',
870
+ LLLL : 'dddd, MMMM D, YYYY LT'
750
871
  },
751
872
  longDateFormat : function (key) {
752
873
  var output = this._longDateFormat[key];
@@ -788,35 +909,37 @@
788
909
  },
789
910
 
790
911
  _relativeTime : {
791
- future : "in %s",
792
- past : "%s ago",
793
- s : "a few seconds",
794
- m : "a minute",
795
- mm : "%d minutes",
796
- h : "an hour",
797
- hh : "%d hours",
798
- d : "a day",
799
- dd : "%d days",
800
- M : "a month",
801
- MM : "%d months",
802
- y : "a year",
803
- yy : "%d years"
912
+ future : 'in %s',
913
+ past : '%s ago',
914
+ s : 'a few seconds',
915
+ m : 'a minute',
916
+ mm : '%d minutes',
917
+ h : 'an hour',
918
+ hh : '%d hours',
919
+ d : 'a day',
920
+ dd : '%d days',
921
+ M : 'a month',
922
+ MM : '%d months',
923
+ y : 'a year',
924
+ yy : '%d years'
804
925
  },
926
+
805
927
  relativeTime : function (number, withoutSuffix, string, isFuture) {
806
928
  var output = this._relativeTime[string];
807
929
  return (typeof output === 'function') ?
808
930
  output(number, withoutSuffix, string, isFuture) :
809
931
  output.replace(/%d/i, number);
810
932
  },
933
+
811
934
  pastFuture : function (diff, output) {
812
935
  var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
813
936
  return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
814
937
  },
815
938
 
816
939
  ordinal : function (number) {
817
- return this._ordinal.replace("%d", number);
940
+ return this._ordinal.replace('%d', number);
818
941
  },
819
- _ordinal : "%d",
942
+ _ordinal : '%d',
820
943
 
821
944
  preparse : function (string) {
822
945
  return string;
@@ -841,78 +964,6 @@
841
964
  }
842
965
  });
843
966
 
844
- // Loads a language definition into the `languages` cache. The function
845
- // takes a key and optionally values. If not in the browser and no values
846
- // are provided, it will load the language file module. As a convenience,
847
- // this function also returns the language values.
848
- function loadLang(key, values) {
849
- values.abbr = key;
850
- if (!languages[key]) {
851
- languages[key] = new Language();
852
- }
853
- languages[key].set(values);
854
- return languages[key];
855
- }
856
-
857
- // Remove a language from the `languages` cache. Mostly useful in tests.
858
- function unloadLang(key) {
859
- delete languages[key];
860
- }
861
-
862
- // Determines which language definition to use and returns it.
863
- //
864
- // With no parameters, it will return the global language. If you
865
- // pass in a language key, such as 'en', it will return the
866
- // definition for 'en', so long as 'en' has already been loaded using
867
- // moment.lang.
868
- function getLangDefinition(key) {
869
- var i = 0, j, lang, next, split,
870
- get = function (k) {
871
- if (!languages[k] && hasModule) {
872
- try {
873
- require('./lang/' + k);
874
- } catch (e) { }
875
- }
876
- return languages[k];
877
- };
878
-
879
- if (!key) {
880
- return moment.fn._lang;
881
- }
882
-
883
- if (!isArray(key)) {
884
- //short-circuit everything else
885
- lang = get(key);
886
- if (lang) {
887
- return lang;
888
- }
889
- key = [key];
890
- }
891
-
892
- //pick the language from the array
893
- //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
894
- //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
895
- while (i < key.length) {
896
- split = normalizeLanguage(key[i]).split('-');
897
- j = split.length;
898
- next = normalizeLanguage(key[i + 1]);
899
- next = next ? next.split('-') : null;
900
- while (j > 0) {
901
- lang = get(split.slice(0, j).join('-'));
902
- if (lang) {
903
- return lang;
904
- }
905
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
906
- //the next array item is better than a shallower substring of this one
907
- break;
908
- }
909
- j--;
910
- }
911
- i++;
912
- }
913
- return moment.fn._lang;
914
- }
915
-
916
967
  /************************************
917
968
  Formatting
918
969
  ************************************/
@@ -920,9 +971,9 @@
920
971
 
921
972
  function removeFormattingTokens(input) {
922
973
  if (input.match(/\[[\s\S]/)) {
923
- return input.replace(/^\[|\]$/g, "");
974
+ return input.replace(/^\[|\]$/g, '');
924
975
  }
925
- return input.replace(/\\/g, "");
976
+ return input.replace(/\\/g, '');
926
977
  }
927
978
 
928
979
  function makeFormatFunction(format) {
@@ -937,7 +988,7 @@
937
988
  }
938
989
 
939
990
  return function (mom) {
940
- var output = "";
991
+ var output = '';
941
992
  for (i = 0; i < length; i++) {
942
993
  output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
943
994
  }
@@ -947,12 +998,11 @@
947
998
 
948
999
  // format date using native date object
949
1000
  function formatMoment(m, format) {
950
-
951
1001
  if (!m.isValid()) {
952
- return m.lang().invalidDate();
1002
+ return m.localeData().invalidDate();
953
1003
  }
954
1004
 
955
- format = expandFormat(format, m.lang());
1005
+ format = expandFormat(format, m.localeData());
956
1006
 
957
1007
  if (!formatFunctions[format]) {
958
1008
  formatFunctions[format] = makeFormatFunction(format);
@@ -961,11 +1011,11 @@
961
1011
  return formatFunctions[format](m);
962
1012
  }
963
1013
 
964
- function expandFormat(format, lang) {
1014
+ function expandFormat(format, locale) {
965
1015
  var i = 5;
966
1016
 
967
1017
  function replaceLongDateFormatTokens(input) {
968
- return lang.longDateFormat(input) || input;
1018
+ return locale.longDateFormat(input) || input;
969
1019
  }
970
1020
 
971
1021
  localFormattingTokens.lastIndex = 0;
@@ -1006,13 +1056,19 @@
1006
1056
  case 'ggggg':
1007
1057
  return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
1008
1058
  case 'S':
1009
- if (strict) { return parseTokenOneDigit; }
1059
+ if (strict) {
1060
+ return parseTokenOneDigit;
1061
+ }
1010
1062
  /* falls through */
1011
1063
  case 'SS':
1012
- if (strict) { return parseTokenTwoDigits; }
1064
+ if (strict) {
1065
+ return parseTokenTwoDigits;
1066
+ }
1013
1067
  /* falls through */
1014
1068
  case 'SSS':
1015
- if (strict) { return parseTokenThreeDigits; }
1069
+ if (strict) {
1070
+ return parseTokenThreeDigits;
1071
+ }
1016
1072
  /* falls through */
1017
1073
  case 'DDD':
1018
1074
  return parseTokenOneToThreeDigits;
@@ -1024,7 +1080,7 @@
1024
1080
  return parseTokenWord;
1025
1081
  case 'a':
1026
1082
  case 'A':
1027
- return getLangDefinition(config._l)._meridiemParse;
1083
+ return config._locale._meridiemParse;
1028
1084
  case 'X':
1029
1085
  return parseTokenTimestampMs;
1030
1086
  case 'Z':
@@ -1061,13 +1117,13 @@
1061
1117
  case 'Do':
1062
1118
  return parseTokenOrdinal;
1063
1119
  default :
1064
- a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
1120
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
1065
1121
  return a;
1066
1122
  }
1067
1123
  }
1068
1124
 
1069
1125
  function timezoneMinutesFromString(string) {
1070
- string = string || "";
1126
+ string = string || '';
1071
1127
  var possibleTzMatches = (string.match(parseTokenTimezone) || []),
1072
1128
  tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
1073
1129
  parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
@@ -1096,7 +1152,7 @@
1096
1152
  break;
1097
1153
  case 'MMM' : // fall through to MMMM
1098
1154
  case 'MMMM' :
1099
- a = getLangDefinition(config._l).monthsParse(input);
1155
+ a = config._locale.monthsParse(input);
1100
1156
  // if we didn't find a month name, mark the date as invalid.
1101
1157
  if (a != null) {
1102
1158
  datePartArray[MONTH] = a;
@@ -1136,7 +1192,7 @@
1136
1192
  // AM / PM
1137
1193
  case 'a' : // fall through to A
1138
1194
  case 'A' :
1139
- config._isPm = getLangDefinition(config._l).isPM(input);
1195
+ config._isPm = config._locale.isPM(input);
1140
1196
  break;
1141
1197
  // 24 HOUR
1142
1198
  case 'H' : // fall through to hh
@@ -1176,7 +1232,7 @@
1176
1232
  case 'dd':
1177
1233
  case 'ddd':
1178
1234
  case 'dddd':
1179
- a = getLangDefinition(config._l).weekdaysParse(input);
1235
+ a = config._locale.weekdaysParse(input);
1180
1236
  // if we didn't get a weekday name, mark the date as invalid
1181
1237
  if (a != null) {
1182
1238
  config._w = config._w || {};
@@ -1212,7 +1268,7 @@
1212
1268
  }
1213
1269
 
1214
1270
  function dayOfYearFromWeekInfo(config) {
1215
- var w, weekYear, week, weekday, dow, doy, temp, lang;
1271
+ var w, weekYear, week, weekday, dow, doy, temp;
1216
1272
 
1217
1273
  w = config._w;
1218
1274
  if (w.GG != null || w.W != null || w.E != null) {
@@ -1227,9 +1283,8 @@
1227
1283
  week = dfl(w.W, 1);
1228
1284
  weekday = dfl(w.E, 1);
1229
1285
  } else {
1230
- lang = getLangDefinition(config._l);
1231
- dow = lang._week.dow;
1232
- doy = lang._week.doy;
1286
+ dow = config._locale._week.dow;
1287
+ doy = config._locale._week.doy;
1233
1288
 
1234
1289
  weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
1235
1290
  week = dfl(w.w, 1);
@@ -1343,7 +1398,6 @@
1343
1398
 
1344
1399
  // date from string and format string
1345
1400
  function makeDateFromStringAndFormat(config) {
1346
-
1347
1401
  if (config._f === moment.ISO_8601) {
1348
1402
  parseISO(config);
1349
1403
  return;
@@ -1353,13 +1407,12 @@
1353
1407
  config._pf.empty = true;
1354
1408
 
1355
1409
  // This array is used to make a Date, either with `new Date` or `Date.UTC`
1356
- var lang = getLangDefinition(config._l),
1357
- string = '' + config._i,
1410
+ var string = '' + config._i,
1358
1411
  i, parsedInput, tokens, token, skipped,
1359
1412
  stringLength = string.length,
1360
1413
  totalParsedInputLength = 0;
1361
1414
 
1362
- tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
1415
+ tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
1363
1416
 
1364
1417
  for (i = 0; i < tokens.length; i++) {
1365
1418
  token = tokens[i];
@@ -1434,7 +1487,7 @@
1434
1487
 
1435
1488
  for (i = 0; i < config._f.length; i++) {
1436
1489
  currentScore = 0;
1437
- tempConfig = extend({}, config);
1490
+ tempConfig = copyConfig({}, config);
1438
1491
  tempConfig._pf = defaultParsingFlags();
1439
1492
  tempConfig._f = config._f[i];
1440
1493
  makeDateFromStringAndFormat(tempConfig);
@@ -1471,7 +1524,7 @@
1471
1524
  for (i = 0, l = isoDates.length; i < l; i++) {
1472
1525
  if (isoDates[i][1].exec(string)) {
1473
1526
  // match[5] should be "T" or undefined
1474
- config._f = isoDates[i][0] + (match[6] || " ");
1527
+ config._f = isoDates[i][0] + (match[6] || ' ');
1475
1528
  break;
1476
1529
  }
1477
1530
  }
@@ -1482,7 +1535,7 @@
1482
1535
  }
1483
1536
  }
1484
1537
  if (string.match(parseTokenTimezone)) {
1485
- config._f += "Z";
1538
+ config._f += 'Z';
1486
1539
  }
1487
1540
  makeDateFromStringAndFormat(config);
1488
1541
  } else {
@@ -1500,20 +1553,18 @@
1500
1553
  }
1501
1554
 
1502
1555
  function makeDateFromInput(config) {
1503
- var input = config._i,
1504
- matched = aspNetJsonRegex.exec(input);
1505
-
1556
+ var input = config._i, matched;
1506
1557
  if (input === undefined) {
1507
1558
  config._d = new Date();
1508
- } else if (matched) {
1559
+ } else if (isDate(input)) {
1560
+ config._d = new Date(+input);
1561
+ } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
1509
1562
  config._d = new Date(+matched[1]);
1510
1563
  } else if (typeof input === 'string') {
1511
1564
  makeDateFromString(config);
1512
1565
  } else if (isArray(input)) {
1513
1566
  config._a = input.slice(0);
1514
1567
  dateFromConfig(config);
1515
- } else if (isDate(input)) {
1516
- config._d = new Date(+input);
1517
1568
  } else if (typeof(input) === 'object') {
1518
1569
  dateFromObject(config);
1519
1570
  } else if (typeof(input) === 'number') {
@@ -1544,13 +1595,13 @@
1544
1595
  return date;
1545
1596
  }
1546
1597
 
1547
- function parseWeekday(input, language) {
1598
+ function parseWeekday(input, locale) {
1548
1599
  if (typeof input === 'string') {
1549
1600
  if (!isNaN(input)) {
1550
1601
  input = parseInt(input, 10);
1551
1602
  }
1552
1603
  else {
1553
- input = language.weekdaysParse(input);
1604
+ input = locale.weekdaysParse(input);
1554
1605
  if (typeof input !== 'number') {
1555
1606
  return null;
1556
1607
  }
@@ -1565,29 +1616,33 @@
1565
1616
 
1566
1617
 
1567
1618
  // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
1568
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
1569
- return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1619
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
1620
+ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1570
1621
  }
1571
1622
 
1572
- function relativeTime(milliseconds, withoutSuffix, lang) {
1573
- var seconds = round(Math.abs(milliseconds) / 1000),
1574
- minutes = round(seconds / 60),
1575
- hours = round(minutes / 60),
1576
- days = round(hours / 24),
1577
- years = round(days / 365),
1578
- args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1623
+ function relativeTime(posNegDuration, withoutSuffix, locale) {
1624
+ var duration = moment.duration(posNegDuration).abs(),
1625
+ seconds = round(duration.as('s')),
1626
+ minutes = round(duration.as('m')),
1627
+ hours = round(duration.as('h')),
1628
+ days = round(duration.as('d')),
1629
+ months = round(duration.as('M')),
1630
+ years = round(duration.as('y')),
1631
+
1632
+ args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1579
1633
  minutes === 1 && ['m'] ||
1580
1634
  minutes < relativeTimeThresholds.m && ['mm', minutes] ||
1581
1635
  hours === 1 && ['h'] ||
1582
1636
  hours < relativeTimeThresholds.h && ['hh', hours] ||
1583
1637
  days === 1 && ['d'] ||
1584
- days <= relativeTimeThresholds.dd && ['dd', days] ||
1585
- days <= relativeTimeThresholds.dm && ['M'] ||
1586
- days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
1638
+ days < relativeTimeThresholds.d && ['dd', days] ||
1639
+ months === 1 && ['M'] ||
1640
+ months < relativeTimeThresholds.M && ['MM', months] ||
1587
1641
  years === 1 && ['y'] || ['yy', years];
1642
+
1588
1643
  args[2] = withoutSuffix;
1589
- args[3] = milliseconds > 0;
1590
- args[4] = lang;
1644
+ args[3] = +posNegDuration > 0;
1645
+ args[4] = locale;
1591
1646
  return substituteTimeAgo.apply({}, args);
1592
1647
  }
1593
1648
 
@@ -1618,7 +1673,7 @@
1618
1673
  daysToDayOfWeek += 7;
1619
1674
  }
1620
1675
 
1621
- adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
1676
+ adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
1622
1677
  return {
1623
1678
  week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1624
1679
  year: adjustedMoment.year()
@@ -1648,18 +1703,18 @@
1648
1703
  var input = config._i,
1649
1704
  format = config._f;
1650
1705
 
1706
+ config._locale = config._locale || moment.localeData(config._l);
1707
+
1651
1708
  if (input === null || (format === undefined && input === '')) {
1652
1709
  return moment.invalid({nullInput: true});
1653
1710
  }
1654
1711
 
1655
1712
  if (typeof input === 'string') {
1656
- config._i = input = getLangDefinition().preparse(input);
1713
+ config._i = input = config._locale.preparse(input);
1657
1714
  }
1658
1715
 
1659
1716
  if (moment.isMoment(input)) {
1660
- config = cloneMoment(input);
1661
-
1662
- config._d = new Date(+input._d);
1717
+ return new Moment(input, true);
1663
1718
  } else if (format) {
1664
1719
  if (isArray(format)) {
1665
1720
  makeDateFromStringAndArray(config);
@@ -1673,12 +1728,12 @@
1673
1728
  return new Moment(config);
1674
1729
  }
1675
1730
 
1676
- moment = function (input, format, lang, strict) {
1731
+ moment = function (input, format, locale, strict) {
1677
1732
  var c;
1678
1733
 
1679
- if (typeof(lang) === "boolean") {
1680
- strict = lang;
1681
- lang = undefined;
1734
+ if (typeof(locale) === "boolean") {
1735
+ strict = locale;
1736
+ locale = undefined;
1682
1737
  }
1683
1738
  // object construction must be done this way.
1684
1739
  // https://github.com/moment/moment/issues/1423
@@ -1686,7 +1741,7 @@
1686
1741
  c._isAMomentObject = true;
1687
1742
  c._i = input;
1688
1743
  c._f = format;
1689
- c._l = lang;
1744
+ c._l = locale;
1690
1745
  c._strict = strict;
1691
1746
  c._isUTC = false;
1692
1747
  c._pf = defaultParsingFlags();
@@ -1697,13 +1752,14 @@
1697
1752
  moment.suppressDeprecationWarnings = false;
1698
1753
 
1699
1754
  moment.createFromInputFallback = deprecate(
1700
- "moment construction falls back to js Date. This is " +
1701
- "discouraged and will be removed in upcoming major " +
1702
- "release. Please refer to " +
1703
- "https://github.com/moment/moment/issues/1407 for more info.",
1704
- function (config) {
1705
- config._d = new Date(config._i);
1706
- });
1755
+ 'moment construction falls back to js Date. This is ' +
1756
+ 'discouraged and will be removed in upcoming major ' +
1757
+ 'release. Please refer to ' +
1758
+ 'https://github.com/moment/moment/issues/1407 for more info.',
1759
+ function (config) {
1760
+ config._d = new Date(config._i);
1761
+ }
1762
+ );
1707
1763
 
1708
1764
  // Pick a moment m from moments so that m[fn](other) is true for all
1709
1765
  // other. This relies on the function fn to be transitive.
@@ -1740,12 +1796,12 @@
1740
1796
  };
1741
1797
 
1742
1798
  // creating with utc
1743
- moment.utc = function (input, format, lang, strict) {
1799
+ moment.utc = function (input, format, locale, strict) {
1744
1800
  var c;
1745
1801
 
1746
- if (typeof(lang) === "boolean") {
1747
- strict = lang;
1748
- lang = undefined;
1802
+ if (typeof(locale) === "boolean") {
1803
+ strict = locale;
1804
+ locale = undefined;
1749
1805
  }
1750
1806
  // object construction must be done this way.
1751
1807
  // https://github.com/moment/moment/issues/1423
@@ -1753,7 +1809,7 @@
1753
1809
  c._isAMomentObject = true;
1754
1810
  c._useUTC = true;
1755
1811
  c._isUTC = true;
1756
- c._l = lang;
1812
+ c._l = locale;
1757
1813
  c._i = input;
1758
1814
  c._f = format;
1759
1815
  c._strict = strict;
@@ -1774,7 +1830,8 @@
1774
1830
  match = null,
1775
1831
  sign,
1776
1832
  ret,
1777
- parseIso;
1833
+ parseIso,
1834
+ diffRes;
1778
1835
 
1779
1836
  if (moment.isDuration(input)) {
1780
1837
  duration = {
@@ -1790,7 +1847,7 @@
1790
1847
  duration.milliseconds = input;
1791
1848
  }
1792
1849
  } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1793
- sign = (match[1] === "-") ? -1 : 1;
1850
+ sign = (match[1] === '-') ? -1 : 1;
1794
1851
  duration = {
1795
1852
  y: 0,
1796
1853
  d: toInt(match[DATE]) * sign,
@@ -1800,7 +1857,7 @@
1800
1857
  ms: toInt(match[MILLISECOND]) * sign
1801
1858
  };
1802
1859
  } else if (!!(match = isoDurationRegex.exec(input))) {
1803
- sign = (match[1] === "-") ? -1 : 1;
1860
+ sign = (match[1] === '-') ? -1 : 1;
1804
1861
  parseIso = function (inp) {
1805
1862
  // We'd normally use ~~inp for this, but unfortunately it also
1806
1863
  // converts floats to ints.
@@ -1818,12 +1875,19 @@
1818
1875
  s: parseIso(match[7]),
1819
1876
  w: parseIso(match[8])
1820
1877
  };
1878
+ } else if (typeof duration === 'object' &&
1879
+ ('from' in duration || 'to' in duration)) {
1880
+ diffRes = momentsDifference(moment(duration.from), moment(duration.to));
1881
+
1882
+ duration = {};
1883
+ duration.ms = diffRes.milliseconds;
1884
+ duration.M = diffRes.months;
1821
1885
  }
1822
1886
 
1823
1887
  ret = new Duration(duration);
1824
1888
 
1825
- if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
1826
- ret._lang = input._lang;
1889
+ if (moment.isDuration(input) && input.hasOwnProperty('_locale')) {
1890
+ ret._locale = input._locale;
1827
1891
  }
1828
1892
 
1829
1893
  return ret;
@@ -1847,40 +1911,93 @@
1847
1911
  moment.updateOffset = function () {};
1848
1912
 
1849
1913
  // This function allows you to set a threshold for relative time strings
1850
- moment.relativeTimeThreshold = function(threshold, limit) {
1851
- if (relativeTimeThresholds[threshold] === undefined) {
1852
- return false;
1853
- }
1854
- relativeTimeThresholds[threshold] = limit;
1855
- return true;
1914
+ moment.relativeTimeThreshold = function (threshold, limit) {
1915
+ if (relativeTimeThresholds[threshold] === undefined) {
1916
+ return false;
1917
+ }
1918
+ if (limit === undefined) {
1919
+ return relativeTimeThresholds[threshold];
1920
+ }
1921
+ relativeTimeThresholds[threshold] = limit;
1922
+ return true;
1856
1923
  };
1857
1924
 
1858
- // This function will load languages and then set the global language. If
1925
+ moment.lang = deprecate(
1926
+ "moment.lang is deprecated. Use moment.locale instead.",
1927
+ function (key, value) {
1928
+ return moment.locale(key, value);
1929
+ }
1930
+ );
1931
+
1932
+ // This function will load locale and then set the global locale. If
1859
1933
  // no arguments are passed in, it will simply return the current global
1860
- // language key.
1861
- moment.lang = function (key, values) {
1862
- var r;
1863
- if (!key) {
1864
- return moment.fn._lang._abbr;
1865
- }
1866
- if (values) {
1867
- loadLang(normalizeLanguage(key), values);
1868
- } else if (values === null) {
1869
- unloadLang(key);
1870
- key = 'en';
1871
- } else if (!languages[key]) {
1872
- getLangDefinition(key);
1873
- }
1874
- r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1875
- return r._abbr;
1934
+ // locale key.
1935
+ moment.locale = function (key, values) {
1936
+ var data;
1937
+ if (key) {
1938
+ if (typeof(values) !== "undefined") {
1939
+ data = moment.defineLocale(key, values);
1940
+ }
1941
+ else {
1942
+ data = moment.localeData(key);
1943
+ }
1944
+
1945
+ if (data) {
1946
+ moment.duration._locale = moment._locale = data;
1947
+ }
1948
+ }
1949
+
1950
+ return moment._locale._abbr;
1876
1951
  };
1877
1952
 
1878
- // returns language data
1879
- moment.langData = function (key) {
1880
- if (key && key._lang && key._lang._abbr) {
1881
- key = key._lang._abbr;
1953
+ moment.defineLocale = function (name, values) {
1954
+ if (values !== null) {
1955
+ values.abbr = name;
1956
+ if (!locales[name]) {
1957
+ locales[name] = new Locale();
1958
+ }
1959
+ locales[name].set(values);
1960
+
1961
+ // backwards compat for now: also set the locale
1962
+ moment.locale(name);
1963
+
1964
+ return locales[name];
1965
+ } else {
1966
+ // useful for testing
1967
+ delete locales[name];
1968
+ return null;
1882
1969
  }
1883
- return getLangDefinition(key);
1970
+ };
1971
+
1972
+ moment.langData = deprecate(
1973
+ "moment.langData is deprecated. Use moment.localeData instead.",
1974
+ function (key) {
1975
+ return moment.localeData(key);
1976
+ }
1977
+ );
1978
+
1979
+ // returns locale data
1980
+ moment.localeData = function (key) {
1981
+ var locale;
1982
+
1983
+ if (key && key._locale && key._locale._abbr) {
1984
+ key = key._locale._abbr;
1985
+ }
1986
+
1987
+ if (!key) {
1988
+ return moment._locale;
1989
+ }
1990
+
1991
+ if (!isArray(key)) {
1992
+ //short-circuit everything else
1993
+ locale = loadLocale(key);
1994
+ if (locale) {
1995
+ return locale;
1996
+ }
1997
+ key = [key];
1998
+ }
1999
+
2000
+ return chooseLocale(key);
1884
2001
  };
1885
2002
 
1886
2003
  // compare moment object
@@ -1942,7 +2059,7 @@
1942
2059
  },
1943
2060
 
1944
2061
  toString : function () {
1945
- return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
2062
+ return this.clone().locale('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1946
2063
  },
1947
2064
 
1948
2065
  toDate : function () {
@@ -1976,7 +2093,6 @@
1976
2093
  },
1977
2094
 
1978
2095
  isDSTShifted : function () {
1979
-
1980
2096
  if (this._a) {
1981
2097
  return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
1982
2098
  }
@@ -1992,48 +2108,30 @@
1992
2108
  return this._pf.overflow;
1993
2109
  },
1994
2110
 
1995
- utc : function () {
1996
- return this.zone(0);
2111
+ utc : function (keepLocalTime) {
2112
+ return this.zone(0, keepLocalTime);
1997
2113
  },
1998
2114
 
1999
- local : function () {
2000
- this.zone(0);
2001
- this._isUTC = false;
2115
+ local : function (keepLocalTime) {
2116
+ if (this._isUTC) {
2117
+ this.zone(0, keepLocalTime);
2118
+ this._isUTC = false;
2119
+
2120
+ if (keepLocalTime) {
2121
+ this.add(this._d.getTimezoneOffset(), 'm');
2122
+ }
2123
+ }
2002
2124
  return this;
2003
2125
  },
2004
2126
 
2005
2127
  format : function (inputString) {
2006
2128
  var output = formatMoment(this, inputString || moment.defaultFormat);
2007
- return this.lang().postformat(output);
2129
+ return this.localeData().postformat(output);
2008
2130
  },
2009
2131
 
2010
- add : function (input, val) {
2011
- var dur;
2012
- // switch args to support add('s', 1) and add(1, 's')
2013
- if (typeof input === 'string' && typeof val === 'string') {
2014
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2015
- } else if (typeof input === 'string') {
2016
- dur = moment.duration(+val, input);
2017
- } else {
2018
- dur = moment.duration(input, val);
2019
- }
2020
- addOrSubtractDurationFromMoment(this, dur, 1);
2021
- return this;
2022
- },
2132
+ add : createAdder(1, 'add'),
2023
2133
 
2024
- subtract : function (input, val) {
2025
- var dur;
2026
- // switch args to support subtract('s', 1) and subtract(1, 's')
2027
- if (typeof input === 'string' && typeof val === 'string') {
2028
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2029
- } else if (typeof input === 'string') {
2030
- dur = moment.duration(+val, input);
2031
- } else {
2032
- dur = moment.duration(input, val);
2033
- }
2034
- addOrSubtractDurationFromMoment(this, dur, -1);
2035
- return this;
2036
- },
2134
+ subtract : createAdder(-1, 'subtract'),
2037
2135
 
2038
2136
  diff : function (input, units, asFloat) {
2039
2137
  var that = makeAs(input, this),
@@ -2070,7 +2168,7 @@
2070
2168
  },
2071
2169
 
2072
2170
  from : function (time, withoutSuffix) {
2073
- return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
2171
+ return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2074
2172
  },
2075
2173
 
2076
2174
  fromNow : function (withoutSuffix) {
@@ -2089,7 +2187,7 @@
2089
2187
  diff < 1 ? 'sameDay' :
2090
2188
  diff < 2 ? 'nextDay' :
2091
2189
  diff < 7 ? 'nextWeek' : 'sameElse';
2092
- return this.format(this.lang().calendar(format, this));
2190
+ return this.format(this.localeData().calendar(format, this));
2093
2191
  },
2094
2192
 
2095
2193
  isLeapYear : function () {
@@ -2104,8 +2202,8 @@
2104
2202
  day : function (input) {
2105
2203
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2106
2204
  if (input != null) {
2107
- input = parseWeekday(input, this.lang());
2108
- return this.add({ d : input - day });
2205
+ input = parseWeekday(input, this.localeData());
2206
+ return this.add(input - day, 'd');
2109
2207
  } else {
2110
2208
  return day;
2111
2209
  }
@@ -2113,7 +2211,7 @@
2113
2211
 
2114
2212
  month : makeAccessor('Month', true),
2115
2213
 
2116
- startOf: function (units) {
2214
+ startOf : function (units) {
2117
2215
  units = normalizeUnits(units);
2118
2216
  // the following switch intentionally omits break keywords
2119
2217
  // to utilize falling through the cases.
@@ -2158,7 +2256,7 @@
2158
2256
 
2159
2257
  endOf: function (units) {
2160
2258
  units = normalizeUnits(units);
2161
- return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
2259
+ return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
2162
2260
  },
2163
2261
 
2164
2262
  isAfter: function (input, units) {
@@ -2177,7 +2275,7 @@
2177
2275
  },
2178
2276
 
2179
2277
  min: deprecate(
2180
- "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
2278
+ 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
2181
2279
  function (other) {
2182
2280
  other = moment.apply(null, arguments);
2183
2281
  return other < this ? this : other;
@@ -2185,36 +2283,43 @@
2185
2283
  ),
2186
2284
 
2187
2285
  max: deprecate(
2188
- "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
2286
+ 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
2189
2287
  function (other) {
2190
2288
  other = moment.apply(null, arguments);
2191
2289
  return other > this ? this : other;
2192
2290
  }
2193
2291
  ),
2194
2292
 
2195
- // keepTime = true means only change the timezone, without affecting
2196
- // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
2197
- // It is possible that 5:31:26 doesn't exist int zone +0200, so we
2198
- // adjust the time as needed, to be valid.
2293
+ // keepLocalTime = true means only change the timezone, without
2294
+ // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
2295
+ // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
2296
+ // +0200, so we adjust the time as needed, to be valid.
2199
2297
  //
2200
2298
  // Keeping the time actually adds/subtracts (one hour)
2201
2299
  // from the actual represented time. That is why we call updateOffset
2202
2300
  // a second time. In case it wants us to change the offset again
2203
2301
  // _changeInProgress == true case, then we have to adjust, because
2204
2302
  // there is no such time in the given timezone.
2205
- zone : function (input, keepTime) {
2206
- var offset = this._offset || 0;
2303
+ zone : function (input, keepLocalTime) {
2304
+ var offset = this._offset || 0,
2305
+ localAdjust;
2207
2306
  if (input != null) {
2208
- if (typeof input === "string") {
2307
+ if (typeof input === 'string') {
2209
2308
  input = timezoneMinutesFromString(input);
2210
2309
  }
2211
2310
  if (Math.abs(input) < 16) {
2212
2311
  input = input * 60;
2213
2312
  }
2313
+ if (!this._isUTC && keepLocalTime) {
2314
+ localAdjust = this._d.getTimezoneOffset();
2315
+ }
2214
2316
  this._offset = input;
2215
2317
  this._isUTC = true;
2318
+ if (localAdjust != null) {
2319
+ this.subtract(localAdjust, 'm');
2320
+ }
2216
2321
  if (offset !== input) {
2217
- if (!keepTime || this._changeInProgress) {
2322
+ if (!keepLocalTime || this._changeInProgress) {
2218
2323
  addOrSubtractDurationFromMoment(this,
2219
2324
  moment.duration(offset - input, 'm'), 1, false);
2220
2325
  } else if (!this._changeInProgress) {
@@ -2230,11 +2335,11 @@
2230
2335
  },
2231
2336
 
2232
2337
  zoneAbbr : function () {
2233
- return this._isUTC ? "UTC" : "";
2338
+ return this._isUTC ? 'UTC' : '';
2234
2339
  },
2235
2340
 
2236
2341
  zoneName : function () {
2237
- return this._isUTC ? "Coordinated Universal Time" : "";
2342
+ return this._isUTC ? 'Coordinated Universal Time' : '';
2238
2343
  },
2239
2344
 
2240
2345
  parseZone : function () {
@@ -2263,7 +2368,7 @@
2263
2368
 
2264
2369
  dayOfYear : function (input) {
2265
2370
  var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
2266
- return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
2371
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2267
2372
  },
2268
2373
 
2269
2374
  quarter : function (input) {
@@ -2271,28 +2376,28 @@
2271
2376
  },
2272
2377
 
2273
2378
  weekYear : function (input) {
2274
- var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
2275
- return input == null ? year : this.add("y", (input - year));
2379
+ var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2380
+ return input == null ? year : this.add((input - year), 'y');
2276
2381
  },
2277
2382
 
2278
2383
  isoWeekYear : function (input) {
2279
2384
  var year = weekOfYear(this, 1, 4).year;
2280
- return input == null ? year : this.add("y", (input - year));
2385
+ return input == null ? year : this.add((input - year), 'y');
2281
2386
  },
2282
2387
 
2283
2388
  week : function (input) {
2284
- var week = this.lang().week(this);
2285
- return input == null ? week : this.add("d", (input - week) * 7);
2389
+ var week = this.localeData().week(this);
2390
+ return input == null ? week : this.add((input - week) * 7, 'd');
2286
2391
  },
2287
2392
 
2288
2393
  isoWeek : function (input) {
2289
2394
  var week = weekOfYear(this, 1, 4).week;
2290
- return input == null ? week : this.add("d", (input - week) * 7);
2395
+ return input == null ? week : this.add((input - week) * 7, 'd');
2291
2396
  },
2292
2397
 
2293
2398
  weekday : function (input) {
2294
- var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
2295
- return input == null ? weekday : this.add("d", input - weekday);
2399
+ var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2400
+ return input == null ? weekday : this.add(input - weekday, 'd');
2296
2401
  },
2297
2402
 
2298
2403
  isoWeekday : function (input) {
@@ -2307,7 +2412,7 @@
2307
2412
  },
2308
2413
 
2309
2414
  weeksInYear : function () {
2310
- var weekInfo = this._lang._week;
2415
+ var weekInfo = this.localeData()._week;
2311
2416
  return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2312
2417
  },
2313
2418
 
@@ -2324,16 +2429,27 @@
2324
2429
  return this;
2325
2430
  },
2326
2431
 
2327
- // If passed a language key, it will set the language for this
2328
- // instance. Otherwise, it will return the language configuration
2432
+ // If passed a locale key, it will set the locale for this
2433
+ // instance. Otherwise, it will return the locale configuration
2329
2434
  // variables for this instance.
2330
- lang : function (key) {
2435
+ locale : function (key) {
2331
2436
  if (key === undefined) {
2332
- return this._lang;
2437
+ return this._locale._abbr;
2333
2438
  } else {
2334
- this._lang = getLangDefinition(key);
2439
+ this._locale = moment.localeData(key);
2335
2440
  return this;
2336
2441
  }
2442
+ },
2443
+
2444
+ lang : deprecate(
2445
+ "moment().lang() is deprecated. Use moment().localeData() instead.",
2446
+ function (key) {
2447
+ return this.localeData(key);
2448
+ }
2449
+ ),
2450
+
2451
+ localeData : function () {
2452
+ return this._locale;
2337
2453
  }
2338
2454
  });
2339
2455
 
@@ -2342,7 +2458,7 @@
2342
2458
 
2343
2459
  // TODO: Move this out of here!
2344
2460
  if (typeof value === 'string') {
2345
- value = mom.lang().monthsParse(value);
2461
+ value = mom.localeData().monthsParse(value);
2346
2462
  // TODO: Another silent failure?
2347
2463
  if (typeof value !== 'number') {
2348
2464
  return mom;
@@ -2389,9 +2505,9 @@
2389
2505
  moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
2390
2506
  // moment.fn.month is defined separately
2391
2507
  moment.fn.date = makeAccessor('Date', true);
2392
- moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
2508
+ moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
2393
2509
  moment.fn.year = makeAccessor('FullYear', true);
2394
- moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
2510
+ moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
2395
2511
 
2396
2512
  // add plural methods
2397
2513
  moment.fn.days = moment.fn.day;
@@ -2408,6 +2524,17 @@
2408
2524
  ************************************/
2409
2525
 
2410
2526
 
2527
+ function daysToYears (days) {
2528
+ // 400 years have 146097 days (taking into account leap year rules)
2529
+ return days * 400 / 146097;
2530
+ }
2531
+
2532
+ function yearsToDays (years) {
2533
+ // years * 365 + absRound(years / 4) -
2534
+ // absRound(years / 100) + absRound(years / 400);
2535
+ return years * 146097 / 400;
2536
+ }
2537
+
2411
2538
  extend(moment.duration.fn = Duration.prototype, {
2412
2539
 
2413
2540
  _bubble : function () {
@@ -2415,7 +2542,7 @@
2415
2542
  days = this._days,
2416
2543
  months = this._months,
2417
2544
  data = this._data,
2418
- seconds, minutes, hours, years;
2545
+ seconds, minutes, hours, years = 0;
2419
2546
 
2420
2547
  // The following code bubbles up values, see the tests for
2421
2548
  // examples of what that means.
@@ -2431,15 +2558,40 @@
2431
2558
  data.hours = hours % 24;
2432
2559
 
2433
2560
  days += absRound(hours / 24);
2434
- data.days = days % 30;
2435
2561
 
2562
+ // Accurately convert days to years, assume start from year 0.
2563
+ years = absRound(daysToYears(days));
2564
+ days -= absRound(yearsToDays(years));
2565
+
2566
+ // 30 days to a month
2567
+ // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2436
2568
  months += absRound(days / 30);
2437
- data.months = months % 12;
2569
+ days %= 30;
2570
+
2571
+ // 12 months -> 1 year
2572
+ years += absRound(months / 12);
2573
+ months %= 12;
2438
2574
 
2439
- years = absRound(months / 12);
2575
+ data.days = days;
2576
+ data.months = months;
2440
2577
  data.years = years;
2441
2578
  },
2442
2579
 
2580
+ abs : function () {
2581
+ this._milliseconds = Math.abs(this._milliseconds);
2582
+ this._days = Math.abs(this._days);
2583
+ this._months = Math.abs(this._months);
2584
+
2585
+ this._data.milliseconds = Math.abs(this._data.milliseconds);
2586
+ this._data.seconds = Math.abs(this._data.seconds);
2587
+ this._data.minutes = Math.abs(this._data.minutes);
2588
+ this._data.hours = Math.abs(this._data.hours);
2589
+ this._data.months = Math.abs(this._data.months);
2590
+ this._data.years = Math.abs(this._data.years);
2591
+
2592
+ return this;
2593
+ },
2594
+
2443
2595
  weeks : function () {
2444
2596
  return absRound(this.days() / 7);
2445
2597
  },
@@ -2452,14 +2604,13 @@
2452
2604
  },
2453
2605
 
2454
2606
  humanize : function (withSuffix) {
2455
- var difference = +this,
2456
- output = relativeTime(difference, !withSuffix, this.lang());
2607
+ var output = relativeTime(this, !withSuffix, this.localeData());
2457
2608
 
2458
2609
  if (withSuffix) {
2459
- output = this.lang().pastFuture(difference, output);
2610
+ output = this.localeData().pastFuture(+this, output);
2460
2611
  }
2461
2612
 
2462
- return this.lang().postformat(output);
2613
+ return this.localeData().postformat(output);
2463
2614
  },
2464
2615
 
2465
2616
  add : function (input, val) {
@@ -2493,13 +2644,39 @@
2493
2644
  },
2494
2645
 
2495
2646
  as : function (units) {
2647
+ var days, months;
2496
2648
  units = normalizeUnits(units);
2497
- return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
2649
+
2650
+ days = this._days + this._milliseconds / 864e5;
2651
+ if (units === 'month' || units === 'year') {
2652
+ months = this._months + daysToYears(days) * 12;
2653
+ return units === 'month' ? months : months / 12;
2654
+ } else {
2655
+ days += yearsToDays(this._months / 12);
2656
+ switch (units) {
2657
+ case 'week': return days / 7;
2658
+ case 'day': return days;
2659
+ case 'hour': return days * 24;
2660
+ case 'minute': return days * 24 * 60;
2661
+ case 'second': return days * 24 * 60 * 60;
2662
+ case 'millisecond': return days * 24 * 60 * 60 * 1000;
2663
+ default: throw new Error('Unknown unit ' + units);
2664
+ }
2665
+ }
2498
2666
  },
2499
2667
 
2500
2668
  lang : moment.fn.lang,
2669
+ locale : moment.fn.locale,
2670
+
2671
+ toIsoString : deprecate(
2672
+ "toIsoString() is deprecated. Please use toISOString() instead " +
2673
+ "(notice the capitals)",
2674
+ function () {
2675
+ return this.toISOString();
2676
+ }
2677
+ ),
2501
2678
 
2502
- toIsoString : function () {
2679
+ toISOString : function () {
2503
2680
  // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2504
2681
  var years = Math.abs(this.years()),
2505
2682
  months = Math.abs(this.months()),
@@ -2523,6 +2700,10 @@
2523
2700
  (hours ? hours + 'H' : '') +
2524
2701
  (minutes ? minutes + 'M' : '') +
2525
2702
  (seconds ? seconds + 'S' : '');
2703
+ },
2704
+
2705
+ localeData : function () {
2706
+ return this._locale;
2526
2707
  }
2527
2708
  });
2528
2709
 
@@ -2532,32 +2713,44 @@
2532
2713
  };
2533
2714
  }
2534
2715
 
2535
- function makeDurationAsGetter(name, factor) {
2536
- moment.duration.fn['as' + name] = function () {
2537
- return +this / factor;
2538
- };
2539
- }
2540
-
2541
2716
  for (i in unitMillisecondFactors) {
2542
2717
  if (unitMillisecondFactors.hasOwnProperty(i)) {
2543
- makeDurationAsGetter(i, unitMillisecondFactors[i]);
2544
2718
  makeDurationGetter(i.toLowerCase());
2545
2719
  }
2546
2720
  }
2547
2721
 
2548
- makeDurationAsGetter('Weeks', 6048e5);
2722
+ moment.duration.fn.asMilliseconds = function () {
2723
+ return this.as('ms');
2724
+ };
2725
+ moment.duration.fn.asSeconds = function () {
2726
+ return this.as('s');
2727
+ };
2728
+ moment.duration.fn.asMinutes = function () {
2729
+ return this.as('m');
2730
+ };
2731
+ moment.duration.fn.asHours = function () {
2732
+ return this.as('h');
2733
+ };
2734
+ moment.duration.fn.asDays = function () {
2735
+ return this.as('d');
2736
+ };
2737
+ moment.duration.fn.asWeeks = function () {
2738
+ return this.as('weeks');
2739
+ };
2549
2740
  moment.duration.fn.asMonths = function () {
2550
- return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
2741
+ return this.as('M');
2742
+ };
2743
+ moment.duration.fn.asYears = function () {
2744
+ return this.as('y');
2551
2745
  };
2552
-
2553
2746
 
2554
2747
  /************************************
2555
- Default Lang
2748
+ Default Locale
2556
2749
  ************************************/
2557
2750
 
2558
2751
 
2559
- // Set default language, other languages will inherit from English.
2560
- moment.lang('en', {
2752
+ // Set default locale, other locale will inherit from English.
2753
+ moment.locale('en', {
2561
2754
  ordinal : function (number) {
2562
2755
  var b = number % 10,
2563
2756
  output = (toInt(number % 100 / 10) === 1) ? 'th' :
@@ -2568,7 +2761,7 @@
2568
2761
  }
2569
2762
  });
2570
2763
 
2571
- /* EMBED_LANGUAGES */
2764
+ /* EMBED_LOCALES */
2572
2765
 
2573
2766
  /************************************
2574
2767
  Exposing Moment
@@ -2582,9 +2775,9 @@
2582
2775
  oldGlobalMoment = globalScope.moment;
2583
2776
  if (shouldDeprecate) {
2584
2777
  globalScope.moment = deprecate(
2585
- "Accessing Moment through the global scope is " +
2586
- "deprecated, and will be removed in an upcoming " +
2587
- "release.",
2778
+ 'Accessing Moment through the global scope is ' +
2779
+ 'deprecated, and will be removed in an upcoming ' +
2780
+ 'release.',
2588
2781
  moment);
2589
2782
  } else {
2590
2783
  globalScope.moment = moment;
@@ -2594,8 +2787,8 @@
2594
2787
  // CommonJS module is defined
2595
2788
  if (hasModule) {
2596
2789
  module.exports = moment;
2597
- } else if (typeof define === "function" && define.amd) {
2598
- define("moment", function (require, exports, module) {
2790
+ } else if (typeof define === 'function' && define.amd) {
2791
+ define('moment', function (require, exports, module) {
2599
2792
  if (module.config && module.config() && module.config().noGlobal === true) {
2600
2793
  // release the global variable
2601
2794
  globalScope.moment = oldGlobalMoment;