momentjs-rails 2.2.1 → 2.4.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/news.md +3 -0
  4. data/test/dummy/log/test.log +147 -14
  5. data/test/dummy/tmp/cache/assets/D1C/680/sprockets%2F16ed4d5afdb2919596e6f8790e2116c2 +0 -0
  6. data/test/dummy/tmp/cache/assets/D35/CA0/sprockets%2F493e64bce2d302801dc01cf7cd096a58 +0 -0
  7. data/test/dummy/tmp/cache/assets/D3F/5F0/sprockets%2F4a6c53eae7c6e41a69a191578bbb6417 +0 -0
  8. data/test/dummy/tmp/cache/assets/D58/BD0/sprockets%2F4de9ddc9b725c715a54c98697b2528fe +0 -0
  9. data/test/dummy/tmp/cache/assets/D75/510/sprockets%2Fe690787ac522f47a6be024bfcc1767ee +0 -0
  10. data/test/dummy/tmp/cache/assets/E10/250/sprockets%2Fe4badb9ddfda484eb9671bf88567be61 +0 -0
  11. data/test/integration/navigation_test.rb +1 -1
  12. data/vendor/assets/javascripts/moment.js +717 -178
  13. data/vendor/assets/javascripts/moment/ar-ma.js +2 -2
  14. data/vendor/assets/javascripts/moment/ar.js +2 -2
  15. data/vendor/assets/javascripts/moment/bg.js +3 -3
  16. data/vendor/assets/javascripts/moment/br.js +2 -2
  17. data/vendor/assets/javascripts/moment/bs.js +139 -0
  18. data/vendor/assets/javascripts/moment/ca.js +2 -2
  19. data/vendor/assets/javascripts/moment/cs.js +2 -2
  20. data/vendor/assets/javascripts/moment/cv.js +2 -2
  21. data/vendor/assets/javascripts/moment/cy.js +77 -0
  22. data/vendor/assets/javascripts/moment/da.js +2 -2
  23. data/vendor/assets/javascripts/moment/de.js +2 -2
  24. data/vendor/assets/javascripts/moment/el.js +2 -2
  25. data/vendor/assets/javascripts/moment/en-au.js +62 -0
  26. data/vendor/assets/javascripts/moment/en-ca.js +2 -2
  27. data/vendor/assets/javascripts/moment/en-gb.js +2 -2
  28. data/vendor/assets/javascripts/moment/eo.js +2 -2
  29. data/vendor/assets/javascripts/moment/es.js +2 -2
  30. data/vendor/assets/javascripts/moment/et.js +2 -2
  31. data/vendor/assets/javascripts/moment/eu.js +2 -2
  32. data/vendor/assets/javascripts/moment/fa.js +2 -2
  33. data/vendor/assets/javascripts/moment/fi.js +2 -2
  34. data/vendor/assets/javascripts/moment/fo.js +56 -0
  35. data/vendor/assets/javascripts/moment/fr-ca.js +2 -2
  36. data/vendor/assets/javascripts/moment/fr.js +2 -2
  37. data/vendor/assets/javascripts/moment/gl.js +2 -2
  38. data/vendor/assets/javascripts/moment/he.js +2 -2
  39. data/vendor/assets/javascripts/moment/hi.js +2 -2
  40. data/vendor/assets/javascripts/moment/hr.js +2 -2
  41. data/vendor/assets/javascripts/moment/hu.js +4 -3
  42. data/vendor/assets/javascripts/moment/id.js +2 -2
  43. data/vendor/assets/javascripts/moment/is.js +2 -2
  44. data/vendor/assets/javascripts/moment/it.js +2 -2
  45. data/vendor/assets/javascripts/moment/ja.js +2 -2
  46. data/vendor/assets/javascripts/moment/ka.js +2 -2
  47. data/vendor/assets/javascripts/moment/ko.js +2 -2
  48. data/vendor/assets/javascripts/moment/lt.js +118 -0
  49. data/vendor/assets/javascripts/moment/lv.js +2 -2
  50. data/vendor/assets/javascripts/moment/ml.js +2 -2
  51. data/vendor/assets/javascripts/moment/mr.js +2 -2
  52. data/vendor/assets/javascripts/moment/ms-my.js +2 -2
  53. data/vendor/assets/javascripts/moment/nb.js +2 -2
  54. data/vendor/assets/javascripts/moment/ne.js +2 -2
  55. data/vendor/assets/javascripts/moment/nl.js +5 -5
  56. data/vendor/assets/javascripts/moment/nn.js +2 -2
  57. data/vendor/assets/javascripts/moment/pl.js +2 -2
  58. data/vendor/assets/javascripts/moment/pt-br.js +2 -2
  59. data/vendor/assets/javascripts/moment/pt.js +2 -2
  60. data/vendor/assets/javascripts/moment/ro.js +2 -2
  61. data/vendor/assets/javascripts/moment/ru.js +20 -5
  62. data/vendor/assets/javascripts/moment/sk.js +2 -2
  63. data/vendor/assets/javascripts/moment/sl.js +2 -2
  64. data/vendor/assets/javascripts/moment/sq.js +2 -2
  65. data/vendor/assets/javascripts/moment/sv.js +2 -2
  66. data/vendor/assets/javascripts/moment/th.js +2 -2
  67. data/vendor/assets/javascripts/moment/tl-ph.js +58 -0
  68. data/vendor/assets/javascripts/moment/tr.js +2 -2
  69. data/vendor/assets/javascripts/moment/tzm-la.js +2 -2
  70. data/vendor/assets/javascripts/moment/tzm.js +2 -2
  71. data/vendor/assets/javascripts/moment/uk.js +18 -3
  72. data/vendor/assets/javascripts/moment/uz.js +55 -0
  73. data/vendor/assets/javascripts/moment/vn.js +62 -0
  74. data/vendor/assets/javascripts/moment/zh-cn.js +43 -18
  75. data/vendor/assets/javascripts/moment/zh-tw.js +7 -6
  76. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e72db56d51cf7e5fe91b467a0b6bfd71734b004e
4
- data.tar.gz: e9160df8b82151849bb7f782d9cbbf1ad57d645d
3
+ metadata.gz: 05d9abfe5085c85b3c1c25276455b53af15e746e
4
+ data.tar.gz: 1b46ea4baeea50dfcc502b5a787ac80cd55f14c6
5
5
  SHA512:
6
- metadata.gz: e578afd22ba49caff9d23d185be3945645f209c57c591c328966bfa0a2c24a76810ce90fa4412080ba4f7b93b37e416cf4d832c62ca0baa0b30f0758fa21fcec
7
- data.tar.gz: 2a12778ba0838e3ee1293f49995fbaa0daeefd79514038725d26e7f6fc1e4f7b7b3a163e0f7559d9b1f49de8915a699dd754620ceed39bbd1e993b3e2d6974e6
6
+ metadata.gz: 64a99f42e2197d11b462e3cd6a2050d4123cf324f0430273fb4bb0fd212ed8ea3155b685485646e45ddcb523753e6416a87730e7ad382becc84a6300a1ac05fb
7
+ data.tar.gz: defb86b1dce99f53e50a9d1a31eba9d42c6a7a7e5d1e7b5843b2ef4928373e6053bf7a5e4319ceb08e0999cdabac6357bc39a5203fa4d23a3172f05b13440990
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.2.1 == Moment.js 2.2.1
27
+ momentjs-rails 2.4.0 == Moment.js 2.4.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.4.0 (2013-11-13)
2
+ - Updated to Moment.js to 2.4.0
3
+
1
4
  ### Version 2.2.1 (2013-09-19)
2
5
  - Updated to Moment.js to 2.2.1
3
6
 
@@ -1,20 +1,153 @@
1
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:00:54 -0400
2
- Compiled moment.js (0ms) (pid 11385)
3
- Served asset /moment.js - 200 OK (6ms)
4
- Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-09-19 11:00:54 -0400
5
- Compiled moment/fr.js (0ms) (pid 11385)
6
- Served asset /moment/fr.js - 200 OK (23ms)
7
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:00:54 -0400
1
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:04:06 -0400
2
+ Compiled moment.js (0ms) (pid 43125)
3
+ Served asset /moment.js - 200 OK (14ms)
4
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:04:06 -0400
5
+ Compiled moment/fr.js (0ms) (pid 43125)
6
+ Served asset /moment/fr.js - 200 OK (96ms)
7
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:05:04 -0400
8
+ Served asset /moment.js - 200 OK (25ms)
9
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:05:04 -0400
10
+ Served asset /moment/fr.js - 200 OK (2ms)
11
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:05:17 -0400
12
+ Served asset /moment.js - 200 OK (2ms)
13
+ Started GET "/assets/momentmotherfucker/fr.js" for 127.0.0.1 at 2013-03-16 16:05:17 -0400
14
+ Served asset /momentmotherfucker/fr.js - 404 Not Found (1ms)
15
+ Started GET "/assets/moments.js" for 127.0.0.1 at 2013-03-16 16:05:53 -0400
16
+ Served asset /moments.js - 404 Not Found (1ms)
17
+ Started GET "/assets/moment/rfr.js" for 127.0.0.1 at 2013-03-16 16:05:53 -0400
18
+ Served asset /moment/rfr.js - 404 Not Found (1ms)
19
+ Started GET "/assets/moments.js" for 127.0.0.1 at 2013-03-16 16:06:02 -0400
20
+ Served asset /moments.js - 404 Not Found (1ms)
21
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:06:02 -0400
22
+ Served asset /moment/fr.js - 200 OK (2ms)
23
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:06:22 -0400
24
+ Served asset /moment.js - 200 OK (2ms)
25
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:06:22 -0400
26
+ Served asset /moment/fr.js - 200 OK (1ms)
27
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:07:08 -0400
28
+ Served asset /moment.js - 200 OK (3ms)
29
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:07:08 -0400
30
+ Served asset /moment/fr.js - 200 OK (1ms)
31
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:08:10 -0400
32
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:08:10 -0400
33
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:08:17 -0400
34
+ Served asset /moment.js - 200 OK (2ms)
35
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:08:17 -0400
36
+ Served asset /moment/fr.js - 200 OK (1ms)
37
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:08:51 -0400
38
+ Served asset /moment.js - 200 OK (2ms)
39
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:08:51 -0400
40
+ Served asset /moment/fr.js - 200 OK (1ms)
41
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:08:57 -0400
42
+ Served asset /moment.js - 200 OK (2ms)
43
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:08:57 -0400
44
+ Served asset /moment/fr.js - 200 OK (1ms)
45
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:09:13 -0400
46
+ Served asset /moment.js - 200 OK (2ms)
47
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:09:13 -0400
48
+ Served asset /moment/fr.js - 200 OK (2ms)
49
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:09:49 -0400
50
+ Served asset /moment.js - 200 OK (2ms)
51
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:09:49 -0400
52
+ Served asset /moment/fr.js - 200 OK (1ms)
53
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:10:05 -0400
54
+ Served asset /moment.js - 200 OK (2ms)
55
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:10:05 -0400
56
+ Served asset /moment/fr.js - 200 OK (1ms)
57
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:11:18 -0400
58
+ Served asset /moment.js - 200 OK (2ms)
59
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:11:18 -0400
60
+ Served asset /moment/fr.js - 200 OK (1ms)
61
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:12:28 -0400
62
+ Served asset /moment.js - 200 OK (16ms)
63
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:12:28 -0400
64
+ Served asset /moment/fr.js - 200 OK (10ms)
65
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:12:47 -0400
66
+ Served asset /moment.js - 200 OK (1ms)
67
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:12:47 -0400
68
+ Served asset /moment/fr.js - 200 OK (11ms)
69
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:14:04 -0400
70
+ Served asset /moment.js - 200 OK (1ms)
71
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:14:04 -0400
72
+ Served asset /moment/fr.js - 200 OK (1ms)
73
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:15:39 -0400
74
+ Served asset /moment.js - 200 OK (1ms)
75
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:15:39 -0400
76
+ Served asset /moment/fr.js - 200 OK (12ms)
77
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:37:24 -0400
78
+ Served asset /moment.js - 200 OK (14ms)
79
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:37:24 -0400
80
+ Served asset /moment/fr.js - 200 OK (11ms)
81
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:37:32 -0400
82
+ Served asset /moment.js - 200 OK (1ms)
83
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:37:32 -0400
84
+ Served asset /moment/fr.js - 200 OK (12ms)
85
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:44:51 -0400
86
+ Served asset /moment.js - 200 OK (46ms)
87
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:44:52 -0400
88
+ Served asset /moment/fr.js - 200 OK (12ms)
89
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:44:52 -0400
90
+ Served asset /moment.js - 200 OK (0ms)
91
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:45:09 -0400
92
+ Served asset /moment.js - 200 OK (1ms)
93
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:45:09 -0400
94
+ Served asset /moment/fr.js - 200 OK (11ms)
95
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:45:09 -0400
96
+ Served asset /moment.js - 200 OK (0ms)
97
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:47:53 -0400
98
+ Compiled moment.js (0ms) (pid 62815)
99
+ Served asset /moment.js - 200 OK (18ms)
100
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:47:53 -0400
101
+ Compiled moment/fr.js (0ms) (pid 62815)
102
+ Served asset /moment/fr.js - 200 OK (18ms)
103
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:47:53 -0400
104
+ Served asset /moment.js - 200 OK (0ms)
105
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:48:16 -0400
106
+ Served asset /moment.js - 200 OK (2ms)
107
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:48:16 -0400
108
+ Served asset /moment/fr.js - 200 OK (1ms)
109
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:48:16 -0400
8
110
  Served asset /moment.js - 200 OK (0ms)
9
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:01:37 -0400
10
- Served asset /moment.js - 200 OK (11ms)
11
- Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-09-19 11:01:37 -0400
111
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:50:40 -0400
112
+ Compiled moment.js (10ms) (pid 64044)
113
+ Served asset /moment.js - 200 OK (40ms)
114
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:50:40 -0400
115
+ Served asset /moment/fr.js - 200 OK (2ms)
116
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:50:40 -0400
117
+ Served asset /moment.js - 200 OK (0ms)
118
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:50:53 -0400
119
+ Compiled moment.js (11ms) (pid 64218)
120
+ Served asset /moment.js - 200 OK (16ms)
121
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-03-16 16:50:53 -0400
12
122
  Served asset /moment/fr.js - 200 OK (1ms)
13
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:01:37 -0400
123
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-03-16 16:50:53 -0400
14
124
  Served asset /moment.js - 200 OK (0ms)
15
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:02:11 -0400
125
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-06-06 21:49:55 -0400
16
126
  Served asset /moment.js - 200 OK (2ms)
17
- Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-09-19 11:02:11 -0400
127
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-06-06 21:49:55 -0400
128
+ Compiled moment/fr.js (0ms) (pid 73048)
129
+ Served asset /moment/fr.js - 200 OK (28ms)
130
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-06-06 21:49:55 -0400
131
+ Served asset /moment.js - 200 OK (0ms)
132
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-07-20 10:00:25 -0400
133
+ Compiled moment.js (0ms) (pid 5373)
134
+ Served asset /moment.js - 200 OK (75ms)
135
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-07-20 10:00:25 -0400
136
+ Compiled moment/fr.js (0ms) (pid 5373)
137
+ Served asset /moment/fr.js - 200 OK (96ms)
138
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-07-20 10:00:25 -0400
139
+ Served asset /moment.js - 200 OK (0ms)
140
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-07-20 10:01:19 -0400
141
+ Served asset /moment.js - 200 OK (2ms)
142
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-07-20 10:01:19 -0400
18
143
  Served asset /moment/fr.js - 200 OK (1ms)
19
- Started GET "/assets/moment.js" for 127.0.0.1 at 2013-09-19 11:02:11 -0400
144
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-07-20 10:01:19 -0400
145
+ Served asset /moment.js - 200 OK (0ms)
146
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-11-14 20:25:32 -0500
147
+ Compiled moment.js (1ms) (pid 43502)
148
+ Served asset /moment.js - 200 OK (78ms)
149
+ Started GET "/assets/moment/fr.js" for 127.0.0.1 at 2013-11-14 20:25:32 -0500
150
+ Compiled moment/fr.js (0ms) (pid 43502)
151
+ Served asset /moment/fr.js - 200 OK (28ms)
152
+ Started GET "/assets/moment.js" for 127.0.0.1 at 2013-11-14 20:25:32 -0500
20
153
  Served asset /moment.js - 200 OK (0ms)
@@ -8,7 +8,7 @@ class NavigationTest < ActionDispatch::IntegrationTest
8
8
 
9
9
  test 'momentjs response is for the expected version' do
10
10
  get 'assets/moment.js'
11
- assert_match(/VERSION = "2\.2\.1"/, @response.body)
11
+ assert_match(/VERSION = "2\.4\.0"/, @response.body)
12
12
  end
13
13
 
14
14
  test 'can access momentjs translation' do
@@ -1,5 +1,5 @@
1
1
  //! moment.js
2
- //! version : 2.2.1
2
+ //! version : 2.4.0
3
3
  //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4
4
  //! license : MIT
5
5
  //! momentjs.com
@@ -11,8 +11,18 @@
11
11
  ************************************/
12
12
 
13
13
  var moment,
14
- VERSION = "2.2.1",
15
- round = Math.round, i,
14
+ VERSION = "2.4.0",
15
+ round = Math.round,
16
+ i,
17
+
18
+ YEAR = 0,
19
+ MONTH = 1,
20
+ DATE = 2,
21
+ HOUR = 3,
22
+ MINUTE = 4,
23
+ SECOND = 5,
24
+ MILLISECOND = 6,
25
+
16
26
  // internal storage for language config files
17
27
  languages = {},
18
28
 
@@ -21,10 +31,14 @@
21
31
 
22
32
  // ASP.NET json date format regex
23
33
  aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
24
- aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
34
+ aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
35
+
36
+ // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
37
+ // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
38
+ isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
25
39
 
26
40
  // format tokens
27
- formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
41
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
28
42
  localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
29
43
 
30
44
  // parsing token regexes
@@ -33,19 +47,28 @@
33
47
  parseTokenThreeDigits = /\d{3}/, // 000 - 999
34
48
  parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
35
49
  parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
50
+ parseTokenDigits = /\d+/, // nonzero number of digits
36
51
  parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
37
52
  parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
38
53
  parseTokenT = /T/i, // T (ISO seperator)
39
54
  parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
40
55
 
41
56
  // preliminary iso regex
42
- // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
43
- isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
57
+ // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000)
58
+ isoRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d:?\d\d|Z)?)?$/,
59
+
44
60
  isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
45
61
 
62
+ isoDates = [
63
+ 'YYYY-MM-DD',
64
+ 'GGGG-[W]WW',
65
+ 'GGGG-[W]WW-E',
66
+ 'YYYY-DDD'
67
+ ],
68
+
46
69
  // iso time formats and regexes
47
70
  isoTimes = [
48
- ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
71
+ ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
49
72
  ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
50
73
  ['HH:mm', /(T| )\d\d:\d\d/],
51
74
  ['HH', /(T| )\d\d/]
@@ -72,10 +95,24 @@
72
95
  m : 'minute',
73
96
  h : 'hour',
74
97
  d : 'day',
98
+ D : 'date',
75
99
  w : 'week',
76
- W : 'isoweek',
100
+ W : 'isoWeek',
77
101
  M : 'month',
78
- y : 'year'
102
+ y : 'year',
103
+ DDD : 'dayOfYear',
104
+ e : 'weekday',
105
+ E : 'isoWeekday',
106
+ gg: 'weekYear',
107
+ GG: 'isoWeekYear'
108
+ },
109
+
110
+ camelFunctions = {
111
+ dayofyear : 'dayOfYear',
112
+ isoweekday : 'isoWeekday',
113
+ isoweek : 'isoWeek',
114
+ weekyear : 'weekYear',
115
+ isoweekyear : 'isoWeekYear'
79
116
  },
80
117
 
81
118
  // format function strings
@@ -171,14 +208,17 @@
171
208
  return this.seconds();
172
209
  },
173
210
  S : function () {
174
- return ~~(this.milliseconds() / 100);
211
+ return toInt(this.milliseconds() / 100);
175
212
  },
176
213
  SS : function () {
177
- return leftZeroFill(~~(this.milliseconds() / 10), 2);
214
+ return leftZeroFill(toInt(this.milliseconds() / 10), 2);
178
215
  },
179
216
  SSS : function () {
180
217
  return leftZeroFill(this.milliseconds(), 3);
181
218
  },
219
+ SSSS : function () {
220
+ return leftZeroFill(this.milliseconds(), 3);
221
+ },
182
222
  Z : function () {
183
223
  var a = -this.zone(),
184
224
  b = "+";
@@ -186,7 +226,7 @@
186
226
  a = -a;
187
227
  b = "-";
188
228
  }
189
- return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
229
+ return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
190
230
  },
191
231
  ZZ : function () {
192
232
  var a = -this.zone(),
@@ -195,7 +235,7 @@
195
235
  a = -a;
196
236
  b = "-";
197
237
  }
198
- return b + leftZeroFill(~~(10 * a / 6), 4);
238
+ return b + leftZeroFill(toInt(10 * a / 6), 4);
199
239
  },
200
240
  z : function () {
201
241
  return this.zoneAbbr();
@@ -206,7 +246,9 @@
206
246
  X : function () {
207
247
  return this.unix();
208
248
  }
209
- };
249
+ },
250
+
251
+ lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
210
252
 
211
253
  function padToken(func, count) {
212
254
  return function (a) {
@@ -240,19 +282,21 @@
240
282
 
241
283
  // Moment prototype object
242
284
  function Moment(config) {
285
+ checkOverflow(config);
243
286
  extend(this, config);
244
287
  }
245
288
 
246
289
  // Duration Constructor
247
290
  function Duration(duration) {
248
- var years = duration.years || duration.year || duration.y || 0,
249
- months = duration.months || duration.month || duration.M || 0,
250
- weeks = duration.weeks || duration.week || duration.w || 0,
251
- days = duration.days || duration.day || duration.d || 0,
252
- hours = duration.hours || duration.hour || duration.h || 0,
253
- minutes = duration.minutes || duration.minute || duration.m || 0,
254
- seconds = duration.seconds || duration.second || duration.s || 0,
255
- milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
291
+ var normalizedInput = normalizeObjectUnits(duration),
292
+ years = normalizedInput.year || 0,
293
+ months = normalizedInput.month || 0,
294
+ weeks = normalizedInput.week || 0,
295
+ days = normalizedInput.day || 0,
296
+ hours = normalizedInput.hour || 0,
297
+ minutes = normalizedInput.minute || 0,
298
+ seconds = normalizedInput.second || 0,
299
+ milliseconds = normalizedInput.millisecond || 0;
256
300
 
257
301
  // store reference to input for deterministic cloning
258
302
  this._input = duration;
@@ -277,7 +321,6 @@
277
321
  this._bubble();
278
322
  }
279
323
 
280
-
281
324
  /************************************
282
325
  Helpers
283
326
  ************************************/
@@ -289,6 +332,15 @@
289
332
  a[i] = b[i];
290
333
  }
291
334
  }
335
+
336
+ if (b.hasOwnProperty("toString")) {
337
+ a.toString = b.toString;
338
+ }
339
+
340
+ if (b.hasOwnProperty("valueOf")) {
341
+ a.valueOf = b.valueOf;
342
+ }
343
+
292
344
  return a;
293
345
  }
294
346
 
@@ -347,14 +399,20 @@
347
399
  return Object.prototype.toString.call(input) === '[object Array]';
348
400
  }
349
401
 
402
+ function isDate(input) {
403
+ return Object.prototype.toString.call(input) === '[object Date]' ||
404
+ input instanceof Date;
405
+ }
406
+
350
407
  // compare two arrays, return the number of differences
351
- function compareArrays(array1, array2) {
408
+ function compareArrays(array1, array2, dontConvert) {
352
409
  var len = Math.min(array1.length, array2.length),
353
410
  lengthDiff = Math.abs(array1.length - array2.length),
354
411
  diffs = 0,
355
412
  i;
356
413
  for (i = 0; i < len; i++) {
357
- if (~~array1[i] !== ~~array2[i]) {
414
+ if ((dontConvert && array1[i] !== array2[i]) ||
415
+ (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
358
416
  diffs++;
359
417
  }
360
418
  }
@@ -362,9 +420,157 @@
362
420
  }
363
421
 
364
422
  function normalizeUnits(units) {
365
- return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
423
+ if (units) {
424
+ var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
425
+ units = unitAliases[units] || camelFunctions[lowered] || lowered;
426
+ }
427
+ return units;
428
+ }
429
+
430
+ function normalizeObjectUnits(inputObject) {
431
+ var normalizedInput = {},
432
+ normalizedProp,
433
+ prop,
434
+ index;
435
+
436
+ for (prop in inputObject) {
437
+ if (inputObject.hasOwnProperty(prop)) {
438
+ normalizedProp = normalizeUnits(prop);
439
+ if (normalizedProp) {
440
+ normalizedInput[normalizedProp] = inputObject[prop];
441
+ }
442
+ }
443
+ }
444
+
445
+ return normalizedInput;
446
+ }
447
+
448
+ function makeList(field) {
449
+ var count, setter;
450
+
451
+ if (field.indexOf('week') === 0) {
452
+ count = 7;
453
+ setter = 'day';
454
+ }
455
+ else if (field.indexOf('month') === 0) {
456
+ count = 12;
457
+ setter = 'month';
458
+ }
459
+ else {
460
+ return;
461
+ }
462
+
463
+ moment[field] = function (format, index) {
464
+ var i, getter,
465
+ method = moment.fn._lang[field],
466
+ results = [];
467
+
468
+ if (typeof format === 'number') {
469
+ index = format;
470
+ format = undefined;
471
+ }
472
+
473
+ getter = function (i) {
474
+ var m = moment().utc().set(setter, i);
475
+ return method.call(moment.fn._lang, m, format || '');
476
+ };
477
+
478
+ if (index != null) {
479
+ return getter(index);
480
+ }
481
+ else {
482
+ for (i = 0; i < count; i++) {
483
+ results.push(getter(i));
484
+ }
485
+ return results;
486
+ }
487
+ };
488
+ }
489
+
490
+ function toInt(argumentForCoercion) {
491
+ var coercedNumber = +argumentForCoercion,
492
+ value = 0;
493
+
494
+ if (coercedNumber !== 0 && isFinite(coercedNumber)) {
495
+ if (coercedNumber >= 0) {
496
+ value = Math.floor(coercedNumber);
497
+ } else {
498
+ value = Math.ceil(coercedNumber);
499
+ }
500
+ }
501
+
502
+ return value;
503
+ }
504
+
505
+ function daysInMonth(year, month) {
506
+ return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
507
+ }
508
+
509
+ function daysInYear(year) {
510
+ return isLeapYear(year) ? 366 : 365;
511
+ }
512
+
513
+ function isLeapYear(year) {
514
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
366
515
  }
367
516
 
517
+ function checkOverflow(m) {
518
+ var overflow;
519
+ if (m._a && m._pf.overflow === -2) {
520
+ overflow =
521
+ m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
522
+ m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
523
+ m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR :
524
+ m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
525
+ m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
526
+ m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
527
+ -1;
528
+
529
+ if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
530
+ overflow = DATE;
531
+ }
532
+
533
+ m._pf.overflow = overflow;
534
+ }
535
+ }
536
+
537
+ function initializeParsingFlags(config) {
538
+ config._pf = {
539
+ empty : false,
540
+ unusedTokens : [],
541
+ unusedInput : [],
542
+ overflow : -2,
543
+ charsLeftOver : 0,
544
+ nullInput : false,
545
+ invalidMonth : null,
546
+ invalidFormat : false,
547
+ userInvalidated : false,
548
+ iso: false
549
+ };
550
+ }
551
+
552
+ function isValid(m) {
553
+ if (m._isValid == null) {
554
+ m._isValid = !isNaN(m._d.getTime()) &&
555
+ m._pf.overflow < 0 &&
556
+ !m._pf.empty &&
557
+ !m._pf.invalidMonth &&
558
+ !m._pf.nullInput &&
559
+ !m._pf.invalidFormat &&
560
+ !m._pf.userInvalidated;
561
+
562
+ if (m._strict) {
563
+ m._isValid = m._isValid &&
564
+ m._pf.charsLeftOver === 0 &&
565
+ m._pf.unusedTokens.length === 0;
566
+ }
567
+ }
568
+ return m._isValid;
569
+ }
570
+
571
+ function normalizeLanguage(key) {
572
+ return key ? key.toLowerCase().replace('_', '-') : key;
573
+ }
368
574
 
369
575
  /************************************
370
576
  Languages
@@ -540,9 +746,15 @@
540
746
  week : function (mom) {
541
747
  return weekOfYear(mom, this._week.dow, this._week.doy).week;
542
748
  },
749
+
543
750
  _week : {
544
751
  dow : 0, // Sunday is the first day of the week.
545
752
  doy : 6 // The week that contains Jan 1st is the first week of the year.
753
+ },
754
+
755
+ _invalidDate: 'Invalid date',
756
+ invalidDate: function () {
757
+ return this._invalidDate;
546
758
  }
547
759
  });
548
760
 
@@ -571,20 +783,52 @@
571
783
  // definition for 'en', so long as 'en' has already been loaded using
572
784
  // moment.lang.
573
785
  function getLangDefinition(key) {
786
+ var i = 0, j, lang, next, split,
787
+ get = function (k) {
788
+ if (!languages[k] && hasModule) {
789
+ try {
790
+ require('./lang/' + k);
791
+ } catch (e) { }
792
+ }
793
+ return languages[k];
794
+ };
795
+
574
796
  if (!key) {
575
797
  return moment.fn._lang;
576
798
  }
577
- if (!languages[key] && hasModule) {
578
- try {
579
- require('./lang/' + key);
580
- } catch (e) {
581
- // call with no params to set to default
582
- return moment.fn._lang;
799
+
800
+ if (!isArray(key)) {
801
+ //short-circuit everything else
802
+ lang = get(key);
803
+ if (lang) {
804
+ return lang;
583
805
  }
806
+ key = [key];
584
807
  }
585
- return languages[key] || moment.fn._lang;
586
- }
587
808
 
809
+ //pick the language from the array
810
+ //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
811
+ //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
812
+ while (i < key.length) {
813
+ split = normalizeLanguage(key[i]).split('-');
814
+ j = split.length;
815
+ next = normalizeLanguage(key[i + 1]);
816
+ next = next ? next.split('-') : null;
817
+ while (j > 0) {
818
+ lang = get(split.slice(0, j).join('-'));
819
+ if (lang) {
820
+ return lang;
821
+ }
822
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
823
+ //the next array item is better than a shallower substring of this one
824
+ break;
825
+ }
826
+ j--;
827
+ }
828
+ i++;
829
+ }
830
+ return moment.fn._lang;
831
+ }
588
832
 
589
833
  /************************************
590
834
  Formatting
@@ -592,7 +836,7 @@
592
836
 
593
837
 
594
838
  function removeFormattingTokens(input) {
595
- if (input.match(/\[.*\]/)) {
839
+ if (input.match(/\[[\s\S]/)) {
596
840
  return input.replace(/^\[|\]$/g, "");
597
841
  }
598
842
  return input.replace(/\\/g, "");
@@ -621,6 +865,10 @@
621
865
  // format date using native date object
622
866
  function formatMoment(m, format) {
623
867
 
868
+ if (!m.isValid()) {
869
+ return m.lang().invalidDate();
870
+ }
871
+
624
872
  format = expandFormat(format, m.lang());
625
873
 
626
874
  if (!formatFunctions[format]) {
@@ -637,9 +885,11 @@
637
885
  return lang.longDateFormat(input) || input;
638
886
  }
639
887
 
640
- while (i-- && (localFormattingTokens.lastIndex = 0,
641
- localFormattingTokens.test(format))) {
888
+ localFormattingTokens.lastIndex = 0;
889
+ while (i >= 0 && localFormattingTokens.test(format)) {
642
890
  format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
891
+ localFormattingTokens.lastIndex = 0;
892
+ i -= 1;
643
893
  }
644
894
 
645
895
  return format;
@@ -653,12 +903,17 @@
653
903
 
654
904
  // get the regex to find the next token
655
905
  function getParseRegexForToken(token, config) {
906
+ var a;
656
907
  switch (token) {
657
908
  case 'DDDD':
658
909
  return parseTokenThreeDigits;
659
910
  case 'YYYY':
911
+ case 'GGGG':
912
+ case 'gggg':
660
913
  return parseTokenFourDigits;
661
914
  case 'YYYYY':
915
+ case 'GGGGG':
916
+ case 'ggggg':
662
917
  return parseTokenSixDigits;
663
918
  case 'S':
664
919
  case 'SS':
@@ -681,9 +936,13 @@
681
936
  return parseTokenTimezone;
682
937
  case 'T':
683
938
  return parseTokenT;
939
+ case 'SSSS':
940
+ return parseTokenDigits;
684
941
  case 'MM':
685
942
  case 'DD':
686
943
  case 'YY':
944
+ case 'GG':
945
+ case 'gg':
687
946
  case 'HH':
688
947
  case 'hh':
689
948
  case 'mm':
@@ -695,16 +954,23 @@
695
954
  case 'h':
696
955
  case 'm':
697
956
  case 's':
957
+ case 'w':
958
+ case 'ww':
959
+ case 'W':
960
+ case 'WW':
961
+ case 'e':
962
+ case 'E':
698
963
  return parseTokenOneOrTwoDigits;
699
964
  default :
700
- return new RegExp(token.replace('\\', ''));
965
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
966
+ return a;
701
967
  }
702
968
  }
703
969
 
704
970
  function timezoneMinutesFromString(string) {
705
971
  var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
706
972
  parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
707
- minutes = +(parts[1] * 60) + ~~parts[2];
973
+ minutes = +(parts[1] * 60) + toInt(parts[2]);
708
974
 
709
975
  return parts[0] === '+' ? -minutes : minutes;
710
976
  }
@@ -718,7 +984,7 @@
718
984
  case 'M' : // fall through to MM
719
985
  case 'MM' :
720
986
  if (input != null) {
721
- datePartArray[1] = ~~input - 1;
987
+ datePartArray[MONTH] = toInt(input) - 1;
722
988
  }
723
989
  break;
724
990
  case 'MMM' : // fall through to MMMM
@@ -726,33 +992,33 @@
726
992
  a = getLangDefinition(config._l).monthsParse(input);
727
993
  // if we didn't find a month name, mark the date as invalid.
728
994
  if (a != null) {
729
- datePartArray[1] = a;
995
+ datePartArray[MONTH] = a;
730
996
  } else {
731
- config._isValid = false;
997
+ config._pf.invalidMonth = input;
732
998
  }
733
999
  break;
734
1000
  // DAY OF MONTH
735
1001
  case 'D' : // fall through to DD
736
1002
  case 'DD' :
737
1003
  if (input != null) {
738
- datePartArray[2] = ~~input;
1004
+ datePartArray[DATE] = toInt(input);
739
1005
  }
740
1006
  break;
741
1007
  // DAY OF YEAR
742
1008
  case 'DDD' : // fall through to DDDD
743
1009
  case 'DDDD' :
744
1010
  if (input != null) {
745
- datePartArray[1] = 0;
746
- datePartArray[2] = ~~input;
1011
+ config._dayOfYear = toInt(input);
747
1012
  }
1013
+
748
1014
  break;
749
1015
  // YEAR
750
1016
  case 'YY' :
751
- datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
1017
+ datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
752
1018
  break;
753
1019
  case 'YYYY' :
754
1020
  case 'YYYYY' :
755
- datePartArray[0] = ~~input;
1021
+ datePartArray[YEAR] = toInt(input);
756
1022
  break;
757
1023
  // AM / PM
758
1024
  case 'a' : // fall through to A
@@ -764,23 +1030,24 @@
764
1030
  case 'HH' : // fall through to hh
765
1031
  case 'h' : // fall through to hh
766
1032
  case 'hh' :
767
- datePartArray[3] = ~~input;
1033
+ datePartArray[HOUR] = toInt(input);
768
1034
  break;
769
1035
  // MINUTE
770
1036
  case 'm' : // fall through to mm
771
1037
  case 'mm' :
772
- datePartArray[4] = ~~input;
1038
+ datePartArray[MINUTE] = toInt(input);
773
1039
  break;
774
1040
  // SECOND
775
1041
  case 's' : // fall through to ss
776
1042
  case 'ss' :
777
- datePartArray[5] = ~~input;
1043
+ datePartArray[SECOND] = toInt(input);
778
1044
  break;
779
1045
  // MILLISECOND
780
1046
  case 'S' :
781
1047
  case 'SS' :
782
1048
  case 'SSS' :
783
- datePartArray[6] = ~~ (('0.' + input) * 1000);
1049
+ case 'SSSS' :
1050
+ datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
784
1051
  break;
785
1052
  // UNIX TIMESTAMP WITH MS
786
1053
  case 'X':
@@ -792,11 +1059,29 @@
792
1059
  config._useUTC = true;
793
1060
  config._tzm = timezoneMinutesFromString(input);
794
1061
  break;
795
- }
796
-
797
- // if the input is null, the date is not valid
798
- if (input == null) {
799
- config._isValid = false;
1062
+ case 'w':
1063
+ case 'ww':
1064
+ case 'W':
1065
+ case 'WW':
1066
+ case 'd':
1067
+ case 'dd':
1068
+ case 'ddd':
1069
+ case 'dddd':
1070
+ case 'e':
1071
+ case 'E':
1072
+ token = token.substr(0, 1);
1073
+ /* falls through */
1074
+ case 'gg':
1075
+ case 'gggg':
1076
+ case 'GG':
1077
+ case 'GGGG':
1078
+ case 'GGGGG':
1079
+ token = token.substr(0, 2);
1080
+ if (input) {
1081
+ config._w = config._w || {};
1082
+ config._w[token] = input;
1083
+ }
1084
+ break;
800
1085
  }
801
1086
  }
802
1087
 
@@ -804,19 +1089,65 @@
804
1089
  // the array should mirror the parameters below
805
1090
  // note: all values past the year are optional and will default to the lowest possible value.
806
1091
  // [year, month, day , hour, minute, second, millisecond]
807
- function dateFromArray(config) {
808
- var i, date, input = [], currentDate;
1092
+ function dateFromConfig(config) {
1093
+ var i, date, input = [], currentDate,
1094
+ yearToUse, fixYear, w, temp, lang, weekday, week;
809
1095
 
810
1096
  if (config._d) {
811
1097
  return;
812
1098
  }
813
1099
 
1100
+ currentDate = currentDateArray(config);
1101
+
1102
+ //compute day of the year from weeks and weekdays
1103
+ if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
1104
+ fixYear = function (val) {
1105
+ return val ?
1106
+ (val.length < 3 ? (parseInt(val, 10) > 68 ? '19' + val : '20' + val) : val) :
1107
+ (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]);
1108
+ };
1109
+
1110
+ w = config._w;
1111
+ if (w.GG != null || w.W != null || w.E != null) {
1112
+ temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1);
1113
+ }
1114
+ else {
1115
+ lang = getLangDefinition(config._l);
1116
+ weekday = w.d != null ? parseWeekday(w.d, lang) :
1117
+ (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0);
1118
+
1119
+ week = parseInt(w.w, 10) || 1;
1120
+
1121
+ //if we're parsing 'd', then the low day numbers may be next week
1122
+ if (w.d != null && weekday < lang._week.dow) {
1123
+ week++;
1124
+ }
1125
+
1126
+ temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow);
1127
+ }
1128
+
1129
+ config._a[YEAR] = temp.year;
1130
+ config._dayOfYear = temp.dayOfYear;
1131
+ }
1132
+
1133
+ //if the day of the year is set, figure out what it is
1134
+ if (config._dayOfYear) {
1135
+ yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR];
1136
+
1137
+ if (config._dayOfYear > daysInYear(yearToUse)) {
1138
+ config._pf._overflowDayOfYear = true;
1139
+ }
1140
+
1141
+ date = makeUTCDate(yearToUse, 0, config._dayOfYear);
1142
+ config._a[MONTH] = date.getUTCMonth();
1143
+ config._a[DATE] = date.getUTCDate();
1144
+ }
1145
+
814
1146
  // Default to current date.
815
1147
  // * if no year, month, day of month are given, default to today
816
1148
  // * if day of month is given, default month and year
817
1149
  // * if month is given, default only year
818
1150
  // * if year is given, don't default anything
819
- currentDate = currentDateArray(config);
820
1151
  for (i = 0; i < 3 && config._a[i] == null; ++i) {
821
1152
  config._a[i] = input[i] = currentDate[i];
822
1153
  }
@@ -827,40 +1158,31 @@
827
1158
  }
828
1159
 
829
1160
  // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
830
- input[3] += ~~((config._tzm || 0) / 60);
831
- input[4] += ~~((config._tzm || 0) % 60);
1161
+ input[HOUR] += toInt((config._tzm || 0) / 60);
1162
+ input[MINUTE] += toInt((config._tzm || 0) % 60);
832
1163
 
833
- date = new Date(0);
834
-
835
- if (config._useUTC) {
836
- date.setUTCFullYear(input[0], input[1], input[2]);
837
- date.setUTCHours(input[3], input[4], input[5], input[6]);
838
- } else {
839
- date.setFullYear(input[0], input[1], input[2]);
840
- date.setHours(input[3], input[4], input[5], input[6]);
841
- }
842
-
843
- config._d = date;
1164
+ config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
844
1165
  }
845
1166
 
846
1167
  function dateFromObject(config) {
847
- var o = config._i;
1168
+ var normalizedInput;
848
1169
 
849
1170
  if (config._d) {
850
1171
  return;
851
1172
  }
852
1173
 
1174
+ normalizedInput = normalizeObjectUnits(config._i);
853
1175
  config._a = [
854
- o.years || o.year || o.y,
855
- o.months || o.month || o.M,
856
- o.days || o.day || o.d,
857
- o.hours || o.hour || o.h,
858
- o.minutes || o.minute || o.m,
859
- o.seconds || o.second || o.s,
860
- o.milliseconds || o.millisecond || o.ms
1176
+ normalizedInput.year,
1177
+ normalizedInput.month,
1178
+ normalizedInput.day,
1179
+ normalizedInput.hour,
1180
+ normalizedInput.minute,
1181
+ normalizedInput.second,
1182
+ normalizedInput.millisecond
861
1183
  ];
862
1184
 
863
- dateFromArray(config);
1185
+ dateFromConfig(config);
864
1186
  }
865
1187
 
866
1188
  function currentDateArray(config) {
@@ -878,74 +1200,116 @@
878
1200
 
879
1201
  // date from string and format string
880
1202
  function makeDateFromStringAndFormat(config) {
1203
+
1204
+ config._a = [];
1205
+ config._pf.empty = true;
1206
+
881
1207
  // This array is used to make a Date, either with `new Date` or `Date.UTC`
882
1208
  var lang = getLangDefinition(config._l),
883
1209
  string = '' + config._i,
884
- i, parsedInput, tokens;
1210
+ i, parsedInput, tokens, token, skipped,
1211
+ stringLength = string.length,
1212
+ totalParsedInputLength = 0;
885
1213
 
886
- tokens = expandFormat(config._f, lang).match(formattingTokens);
887
-
888
- config._a = [];
1214
+ tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
889
1215
 
890
1216
  for (i = 0; i < tokens.length; i++) {
891
- parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
1217
+ token = tokens[i];
1218
+ parsedInput = (getParseRegexForToken(token, config).exec(string) || [])[0];
892
1219
  if (parsedInput) {
1220
+ skipped = string.substr(0, string.indexOf(parsedInput));
1221
+ if (skipped.length > 0) {
1222
+ config._pf.unusedInput.push(skipped);
1223
+ }
893
1224
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
1225
+ totalParsedInputLength += parsedInput.length;
894
1226
  }
895
- // don't parse if its not a known token
896
- if (formatTokenFunctions[tokens[i]]) {
897
- addTimeToArrayFromToken(tokens[i], parsedInput, config);
1227
+ // don't parse if it's not a known token
1228
+ if (formatTokenFunctions[token]) {
1229
+ if (parsedInput) {
1230
+ config._pf.empty = false;
1231
+ }
1232
+ else {
1233
+ config._pf.unusedTokens.push(token);
1234
+ }
1235
+ addTimeToArrayFromToken(token, parsedInput, config);
1236
+ }
1237
+ else if (config._strict && !parsedInput) {
1238
+ config._pf.unusedTokens.push(token);
898
1239
  }
899
1240
  }
900
1241
 
901
- // add remaining unparsed input to the string
902
- if (string) {
903
- config._il = string;
1242
+ // add remaining unparsed input length to the string
1243
+ config._pf.charsLeftOver = stringLength - totalParsedInputLength;
1244
+ if (string.length > 0) {
1245
+ config._pf.unusedInput.push(string);
904
1246
  }
905
1247
 
906
1248
  // handle am pm
907
- if (config._isPm && config._a[3] < 12) {
908
- config._a[3] += 12;
1249
+ if (config._isPm && config._a[HOUR] < 12) {
1250
+ config._a[HOUR] += 12;
909
1251
  }
910
1252
  // if is 12 am, change hours to 0
911
- if (config._isPm === false && config._a[3] === 12) {
912
- config._a[3] = 0;
1253
+ if (config._isPm === false && config._a[HOUR] === 12) {
1254
+ config._a[HOUR] = 0;
913
1255
  }
914
- // return
915
- dateFromArray(config);
1256
+
1257
+ dateFromConfig(config);
1258
+ checkOverflow(config);
1259
+ }
1260
+
1261
+ function unescapeFormat(s) {
1262
+ return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
1263
+ return p1 || p2 || p3 || p4;
1264
+ });
1265
+ }
1266
+
1267
+ // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
1268
+ function regexpEscape(s) {
1269
+ return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
916
1270
  }
917
1271
 
918
1272
  // date from string and array of format strings
919
1273
  function makeDateFromStringAndArray(config) {
920
1274
  var tempConfig,
921
- tempMoment,
922
1275
  bestMoment,
923
1276
 
924
- scoreToBeat = 99,
1277
+ scoreToBeat,
925
1278
  i,
926
1279
  currentScore;
927
1280
 
1281
+ if (config._f.length === 0) {
1282
+ config._pf.invalidFormat = true;
1283
+ config._d = new Date(NaN);
1284
+ return;
1285
+ }
1286
+
928
1287
  for (i = 0; i < config._f.length; i++) {
1288
+ currentScore = 0;
929
1289
  tempConfig = extend({}, config);
1290
+ initializeParsingFlags(tempConfig);
930
1291
  tempConfig._f = config._f[i];
931
1292
  makeDateFromStringAndFormat(tempConfig);
932
- tempMoment = new Moment(tempConfig);
933
-
934
- currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
935
1293
 
936
- // if there is any input that was not parsed
937
- // add a penalty for that format
938
- if (tempMoment._il) {
939
- currentScore += tempMoment._il.length;
1294
+ if (!isValid(tempConfig)) {
1295
+ continue;
940
1296
  }
941
1297
 
942
- if (currentScore < scoreToBeat) {
1298
+ // if there is any input that was not parsed add a penalty for that format
1299
+ currentScore += tempConfig._pf.charsLeftOver;
1300
+
1301
+ //or tokens
1302
+ currentScore += tempConfig._pf.unusedTokens.length * 10;
1303
+
1304
+ tempConfig._pf.score = currentScore;
1305
+
1306
+ if (scoreToBeat == null || currentScore < scoreToBeat) {
943
1307
  scoreToBeat = currentScore;
944
- bestMoment = tempMoment;
1308
+ bestMoment = tempConfig;
945
1309
  }
946
1310
  }
947
1311
 
948
- extend(config, bestMoment);
1312
+ extend(config, bestMoment || tempConfig);
949
1313
  }
950
1314
 
951
1315
  // date from iso format
@@ -955,8 +1319,14 @@
955
1319
  match = isoRegex.exec(string);
956
1320
 
957
1321
  if (match) {
958
- // match[2] should be "T" or undefined
959
- config._f = 'YYYY-MM-DD' + (match[2] || " ");
1322
+ config._pf.iso = true;
1323
+ for (i = 4; i > 0; i--) {
1324
+ if (match[i]) {
1325
+ // match[5] should be "T" or undefined
1326
+ config._f = isoDates[i - 1] + (match[6] || " ");
1327
+ break;
1328
+ }
1329
+ }
960
1330
  for (i = 0; i < 4; i++) {
961
1331
  if (isoTimes[i][1].exec(string)) {
962
1332
  config._f += isoTimes[i][0];
@@ -964,10 +1334,11 @@
964
1334
  }
965
1335
  }
966
1336
  if (parseTokenTimezone.exec(string)) {
967
- config._f += " Z";
1337
+ config._f += "Z";
968
1338
  }
969
1339
  makeDateFromStringAndFormat(config);
970
- } else {
1340
+ }
1341
+ else {
971
1342
  config._d = new Date(string);
972
1343
  }
973
1344
  }
@@ -984,8 +1355,8 @@
984
1355
  makeDateFromString(config);
985
1356
  } else if (isArray(input)) {
986
1357
  config._a = input.slice(0);
987
- dateFromArray(config);
988
- } else if (input instanceof Date) {
1358
+ dateFromConfig(config);
1359
+ } else if (isDate(input)) {
989
1360
  config._d = new Date(+input);
990
1361
  } else if (typeof(input) === 'object') {
991
1362
  dateFromObject(config);
@@ -994,6 +1365,40 @@
994
1365
  }
995
1366
  }
996
1367
 
1368
+ function makeDate(y, m, d, h, M, s, ms) {
1369
+ //can't just apply() to create a date:
1370
+ //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
1371
+ var date = new Date(y, m, d, h, M, s, ms);
1372
+
1373
+ //the date constructor doesn't accept years < 1970
1374
+ if (y < 1970) {
1375
+ date.setFullYear(y);
1376
+ }
1377
+ return date;
1378
+ }
1379
+
1380
+ function makeUTCDate(y) {
1381
+ var date = new Date(Date.UTC.apply(null, arguments));
1382
+ if (y < 1970) {
1383
+ date.setUTCFullYear(y);
1384
+ }
1385
+ return date;
1386
+ }
1387
+
1388
+ function parseWeekday(input, language) {
1389
+ if (typeof input === 'string') {
1390
+ if (!isNaN(input)) {
1391
+ input = parseInt(input, 10);
1392
+ }
1393
+ else {
1394
+ input = language.weekdaysParse(input);
1395
+ if (typeof input !== 'number') {
1396
+ return null;
1397
+ }
1398
+ }
1399
+ }
1400
+ return input;
1401
+ }
997
1402
 
998
1403
  /************************************
999
1404
  Relative Time
@@ -1061,6 +1466,20 @@
1061
1466
  };
1062
1467
  }
1063
1468
 
1469
+ //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1470
+ function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
1471
+ var d = new Date(Date.UTC(year, 0)).getUTCDay(),
1472
+ daysToAdd, dayOfYear;
1473
+
1474
+ weekday = weekday != null ? weekday : firstDayOfWeek;
1475
+ daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0);
1476
+ dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
1477
+
1478
+ return {
1479
+ year: dayOfYear > 0 ? year : year - 1,
1480
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
1481
+ };
1482
+ }
1064
1483
 
1065
1484
  /************************************
1066
1485
  Top Level Functions
@@ -1070,8 +1489,12 @@
1070
1489
  var input = config._i,
1071
1490
  format = config._f;
1072
1491
 
1073
- if (input === null || input === '') {
1074
- return null;
1492
+ if (typeof config._pf === 'undefined') {
1493
+ initializeParsingFlags(config);
1494
+ }
1495
+
1496
+ if (input === null) {
1497
+ return moment.invalid({nullInput: true});
1075
1498
  }
1076
1499
 
1077
1500
  if (typeof input === 'string') {
@@ -1080,6 +1503,7 @@
1080
1503
 
1081
1504
  if (moment.isMoment(input)) {
1082
1505
  config = extend({}, input);
1506
+
1083
1507
  config._d = new Date(+input._d);
1084
1508
  } else if (format) {
1085
1509
  if (isArray(format)) {
@@ -1094,24 +1518,38 @@
1094
1518
  return new Moment(config);
1095
1519
  }
1096
1520
 
1097
- moment = function (input, format, lang) {
1521
+ moment = function (input, format, lang, strict) {
1522
+ if (typeof(lang) === "boolean") {
1523
+ strict = lang;
1524
+ lang = undefined;
1525
+ }
1098
1526
  return makeMoment({
1099
1527
  _i : input,
1100
1528
  _f : format,
1101
1529
  _l : lang,
1530
+ _strict : strict,
1102
1531
  _isUTC : false
1103
1532
  });
1104
1533
  };
1105
1534
 
1106
1535
  // creating with utc
1107
- moment.utc = function (input, format, lang) {
1108
- return makeMoment({
1536
+ moment.utc = function (input, format, lang, strict) {
1537
+ var m;
1538
+
1539
+ if (typeof(lang) === "boolean") {
1540
+ strict = lang;
1541
+ lang = undefined;
1542
+ }
1543
+ m = makeMoment({
1109
1544
  _useUTC : true,
1110
1545
  _isUTC : true,
1111
1546
  _l : lang,
1112
1547
  _i : input,
1113
- _f : format
1548
+ _f : format,
1549
+ _strict : strict
1114
1550
  }).utc();
1551
+
1552
+ return m;
1115
1553
  };
1116
1554
 
1117
1555
  // creating with unix timestamp (in seconds)
@@ -1124,9 +1562,13 @@
1124
1562
  var isDuration = moment.isDuration(input),
1125
1563
  isNumber = (typeof input === 'number'),
1126
1564
  duration = (isDuration ? input._input : (isNumber ? {} : input)),
1127
- matched = aspNetTimeSpanJsonRegex.exec(input),
1565
+ // matching against regexp is expensive, do it on demand
1566
+ match = null,
1128
1567
  sign,
1129
- ret;
1568
+ ret,
1569
+ parseIso,
1570
+ timeEmpty,
1571
+ dateTimeEmpty;
1130
1572
 
1131
1573
  if (isNumber) {
1132
1574
  if (key) {
@@ -1134,15 +1576,34 @@
1134
1576
  } else {
1135
1577
  duration.milliseconds = input;
1136
1578
  }
1137
- } else if (matched) {
1138
- sign = (matched[1] === "-") ? -1 : 1;
1579
+ } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1580
+ sign = (match[1] === "-") ? -1 : 1;
1139
1581
  duration = {
1140
1582
  y: 0,
1141
- d: ~~matched[2] * sign,
1142
- h: ~~matched[3] * sign,
1143
- m: ~~matched[4] * sign,
1144
- s: ~~matched[5] * sign,
1145
- ms: ~~matched[6] * sign
1583
+ d: toInt(match[DATE]) * sign,
1584
+ h: toInt(match[HOUR]) * sign,
1585
+ m: toInt(match[MINUTE]) * sign,
1586
+ s: toInt(match[SECOND]) * sign,
1587
+ ms: toInt(match[MILLISECOND]) * sign
1588
+ };
1589
+ } else if (!!(match = isoDurationRegex.exec(input))) {
1590
+ sign = (match[1] === "-") ? -1 : 1;
1591
+ parseIso = function (inp) {
1592
+ // We'd normally use ~~inp for this, but unfortunately it also
1593
+ // converts floats to ints.
1594
+ // inp may be undefined, so careful calling replace on it.
1595
+ var res = inp && parseFloat(inp.replace(',', '.'));
1596
+ // apply sign while we're at it
1597
+ return (isNaN(res) ? 0 : res) * sign;
1598
+ };
1599
+ duration = {
1600
+ y: parseIso(match[2]),
1601
+ M: parseIso(match[3]),
1602
+ d: parseIso(match[4]),
1603
+ h: parseIso(match[5]),
1604
+ m: parseIso(match[6]),
1605
+ s: parseIso(match[7]),
1606
+ w: parseIso(match[8])
1146
1607
  };
1147
1608
  }
1148
1609
 
@@ -1169,20 +1630,20 @@
1169
1630
  // no arguments are passed in, it will simply return the current global
1170
1631
  // language key.
1171
1632
  moment.lang = function (key, values) {
1633
+ var r;
1172
1634
  if (!key) {
1173
1635
  return moment.fn._lang._abbr;
1174
1636
  }
1175
- key = key.toLowerCase();
1176
- key = key.replace('_', '-');
1177
1637
  if (values) {
1178
- loadLang(key, values);
1638
+ loadLang(normalizeLanguage(key), values);
1179
1639
  } else if (values === null) {
1180
1640
  unloadLang(key);
1181
1641
  key = 'en';
1182
1642
  } else if (!languages[key]) {
1183
1643
  getLangDefinition(key);
1184
1644
  }
1185
- moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1645
+ r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1646
+ return r._abbr;
1186
1647
  };
1187
1648
 
1188
1649
  // returns language data
@@ -1203,6 +1664,29 @@
1203
1664
  return obj instanceof Duration;
1204
1665
  };
1205
1666
 
1667
+ for (i = lists.length - 1; i >= 0; --i) {
1668
+ makeList(lists[i]);
1669
+ }
1670
+
1671
+ moment.normalizeUnits = function (units) {
1672
+ return normalizeUnits(units);
1673
+ };
1674
+
1675
+ moment.invalid = function (flags) {
1676
+ var m = moment.utc(NaN);
1677
+ if (flags != null) {
1678
+ extend(m._pf, flags);
1679
+ }
1680
+ else {
1681
+ m._pf.userInvalidated = true;
1682
+ }
1683
+
1684
+ return m;
1685
+ };
1686
+
1687
+ moment.parseZone = function (input) {
1688
+ return moment(input).parseZone();
1689
+ };
1206
1690
 
1207
1691
  /************************************
1208
1692
  Moment Prototype
@@ -1224,7 +1708,7 @@
1224
1708
  },
1225
1709
 
1226
1710
  toString : function () {
1227
- return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1711
+ return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1228
1712
  },
1229
1713
 
1230
1714
  toDate : function () {
@@ -1249,22 +1733,24 @@
1249
1733
  },
1250
1734
 
1251
1735
  isValid : function () {
1252
- if (this._isValid == null) {
1253
- if (this._a) {
1254
- this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray());
1255
- } else {
1256
- this._isValid = !isNaN(this._d.getTime());
1257
- }
1736
+ return isValid(this);
1737
+ },
1738
+
1739
+ isDSTShifted : function () {
1740
+
1741
+ if (this._a) {
1742
+ return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
1258
1743
  }
1259
- return !!this._isValid;
1744
+
1745
+ return false;
1746
+ },
1747
+
1748
+ parsingFlags : function () {
1749
+ return extend({}, this._pf);
1260
1750
  },
1261
1751
 
1262
1752
  invalidAt: function () {
1263
- var i, arr1 = this._a, arr2 = (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray();
1264
- for (i = 6; i >= 0 && arr1[i] === arr2[i]; --i) {
1265
- // empty loop body
1266
- }
1267
- return i;
1753
+ return this._pf.overflow;
1268
1754
  },
1269
1755
 
1270
1756
  utc : function () {
@@ -1360,8 +1846,7 @@
1360
1846
  },
1361
1847
 
1362
1848
  isLeapYear : function () {
1363
- var year = this.year();
1364
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1849
+ return isLeapYear(this.year());
1365
1850
  },
1366
1851
 
1367
1852
  isDST : function () {
@@ -1372,12 +1857,7 @@
1372
1857
  day : function (input) {
1373
1858
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1374
1859
  if (input != null) {
1375
- if (typeof input === 'string') {
1376
- input = this.lang().weekdaysParse(input);
1377
- if (typeof input !== 'number') {
1378
- return this;
1379
- }
1380
- }
1860
+ input = parseWeekday(input, this.lang());
1381
1861
  return this.add({ d : input - day });
1382
1862
  } else {
1383
1863
  return day;
@@ -1420,7 +1900,7 @@
1420
1900
  this.date(1);
1421
1901
  /* falls through */
1422
1902
  case 'week':
1423
- case 'isoweek':
1903
+ case 'isoWeek':
1424
1904
  case 'day':
1425
1905
  this.hours(0);
1426
1906
  /* falls through */
@@ -1438,7 +1918,7 @@
1438
1918
  // weeks are a special case
1439
1919
  if (units === 'week') {
1440
1920
  this.weekday(0);
1441
- } else if (units === 'isoweek') {
1921
+ } else if (units === 'isoWeek') {
1442
1922
  this.isoWeekday(1);
1443
1923
  }
1444
1924
 
@@ -1447,7 +1927,7 @@
1447
1927
 
1448
1928
  endOf: function (units) {
1449
1929
  units = normalizeUnits(units);
1450
- return this.startOf(units).add((units === 'isoweek' ? 'week' : units), 1).subtract('ms', 1);
1930
+ return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
1451
1931
  },
1452
1932
 
1453
1933
  isAfter: function (input, units) {
@@ -1503,6 +1983,13 @@
1503
1983
  return this._isUTC ? "Coordinated Universal Time" : "";
1504
1984
  },
1505
1985
 
1986
+ parseZone : function () {
1987
+ if (typeof this._i === 'string') {
1988
+ this.zone(this._i);
1989
+ }
1990
+ return this;
1991
+ },
1992
+
1506
1993
  hasAlignedHourOffset : function (input) {
1507
1994
  if (!input) {
1508
1995
  input = 0;
@@ -1515,7 +2002,7 @@
1515
2002
  },
1516
2003
 
1517
2004
  daysInMonth : function () {
1518
- return moment.utc([this.year(), this.month() + 1, 0]).date();
2005
+ return daysInMonth(this.year(), this.month());
1519
2006
  },
1520
2007
 
1521
2008
  dayOfYear : function (input) {
@@ -1544,7 +2031,7 @@
1544
2031
  },
1545
2032
 
1546
2033
  weekday : function (input) {
1547
- var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
2034
+ var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
1548
2035
  return input == null ? weekday : this.add("d", input - weekday);
1549
2036
  },
1550
2037
 
@@ -1557,12 +2044,15 @@
1557
2044
 
1558
2045
  get : function (units) {
1559
2046
  units = normalizeUnits(units);
1560
- return this[units.toLowerCase()]();
2047
+ return this[units]();
1561
2048
  },
1562
2049
 
1563
2050
  set : function (units, value) {
1564
2051
  units = normalizeUnits(units);
1565
- this[units.toLowerCase()](value);
2052
+ if (typeof this[units] === 'function') {
2053
+ this[units](value);
2054
+ }
2055
+ return this;
1566
2056
  },
1567
2057
 
1568
2058
  // If passed a language key, it will set the language for this
@@ -1654,7 +2144,7 @@
1654
2144
  return this._milliseconds +
1655
2145
  this._days * 864e5 +
1656
2146
  (this._months % 12) * 2592e6 +
1657
- ~~(this._months / 12) * 31536e6;
2147
+ toInt(this._months / 12) * 31536e6;
1658
2148
  },
1659
2149
 
1660
2150
  humanize : function (withSuffix) {
@@ -1703,7 +2193,33 @@
1703
2193
  return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
1704
2194
  },
1705
2195
 
1706
- lang : moment.fn.lang
2196
+ lang : moment.fn.lang,
2197
+
2198
+ toIsoString : function () {
2199
+ // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2200
+ var years = Math.abs(this.years()),
2201
+ months = Math.abs(this.months()),
2202
+ days = Math.abs(this.days()),
2203
+ hours = Math.abs(this.hours()),
2204
+ minutes = Math.abs(this.minutes()),
2205
+ seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
2206
+
2207
+ if (!this.asSeconds()) {
2208
+ // this is the same as C#'s (Noda) and python (isodate)...
2209
+ // but not other JS (goog.date)
2210
+ return 'P0D';
2211
+ }
2212
+
2213
+ return (this.asSeconds() < 0 ? '-' : '') +
2214
+ 'P' +
2215
+ (years ? years + 'Y' : '') +
2216
+ (months ? months + 'M' : '') +
2217
+ (days ? days + 'D' : '') +
2218
+ ((hours || minutes || seconds) ? 'T' : '') +
2219
+ (hours ? hours + 'H' : '') +
2220
+ (minutes ? minutes + 'M' : '') +
2221
+ (seconds ? seconds + 'S' : '');
2222
+ }
1707
2223
  });
1708
2224
 
1709
2225
  function makeDurationGetter(name) {
@@ -1740,7 +2256,7 @@
1740
2256
  moment.lang('en', {
1741
2257
  ordinal : function (number) {
1742
2258
  var b = number % 10,
1743
- output = (~~ (number % 100 / 10) === 1) ? 'th' :
2259
+ output = (toInt(number % 100 / 10) === 1) ? 'th' :
1744
2260
  (b === 1) ? 'st' :
1745
2261
  (b === 2) ? 'nd' :
1746
2262
  (b === 3) ? 'rd' : 'th';
@@ -1754,22 +2270,45 @@
1754
2270
  Exposing Moment
1755
2271
  ************************************/
1756
2272
 
1757
-
1758
- // CommonJS module is defined
1759
- if (hasModule) {
1760
- module.exports = moment;
1761
- }
1762
- /*global ender:false */
1763
- if (typeof ender === 'undefined') {
2273
+ function makeGlobal(deprecate) {
2274
+ var warned = false, local_moment = moment;
2275
+ /*global ender:false */
2276
+ if (typeof ender !== 'undefined') {
2277
+ return;
2278
+ }
1764
2279
  // here, `this` means `window` in the browser, or `global` on the server
1765
2280
  // add `moment` as a global object via a string identifier,
1766
2281
  // for Closure Compiler "advanced" mode
1767
- this['moment'] = moment;
2282
+ if (deprecate) {
2283
+ this.moment = function () {
2284
+ if (!warned && console && console.warn) {
2285
+ warned = true;
2286
+ console.warn(
2287
+ "Accessing Moment through the global scope is " +
2288
+ "deprecated, and will be removed in an upcoming " +
2289
+ "release.");
2290
+ }
2291
+ return local_moment.apply(null, arguments);
2292
+ };
2293
+ } else {
2294
+ this['moment'] = moment;
2295
+ }
1768
2296
  }
1769
- /*global define:false */
1770
- if (typeof define === "function" && define.amd) {
1771
- define("moment", [], function () {
2297
+
2298
+ // CommonJS module is defined
2299
+ if (hasModule) {
2300
+ module.exports = moment;
2301
+ makeGlobal(true);
2302
+ } else if (typeof define === "function" && define.amd) {
2303
+ define("moment", function (require, exports, module) {
2304
+ if (module.config().noGlobal !== true) {
2305
+ // If user provided noGlobal, he is aware of global
2306
+ makeGlobal(module.config().noGlobal === undefined);
2307
+ }
2308
+
1772
2309
  return moment;
1773
2310
  });
2311
+ } else {
2312
+ makeGlobal();
1774
2313
  }
1775
2314
  }).call(this);