momentjs-rails 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
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;