date-and-time 1.0.1 → 2.1.1

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 (136) hide show
  1. package/EXTEND.md +28 -10
  2. package/LOCALE.md +1 -0
  3. package/PLUGINS.md +185 -63
  4. package/README.md +61 -46
  5. package/date-and-time.js +140 -102
  6. package/date-and-time.min.js +12 -12
  7. package/esm/date-and-time.es.js +138 -100
  8. package/esm/date-and-time.es.min.js +13 -12
  9. package/esm/date-and-time.mjs +138 -100
  10. package/esm/locale/ar.es.js +1 -1
  11. package/esm/locale/ar.mjs +1 -1
  12. package/esm/locale/az.es.js +1 -1
  13. package/esm/locale/az.mjs +1 -1
  14. package/esm/locale/bn.es.js +1 -1
  15. package/esm/locale/bn.mjs +1 -1
  16. package/esm/locale/cs.es.js +1 -1
  17. package/esm/locale/cs.mjs +1 -1
  18. package/esm/locale/de.es.js +1 -1
  19. package/esm/locale/de.mjs +1 -1
  20. package/esm/locale/dk.es.js +1 -1
  21. package/esm/locale/dk.mjs +1 -1
  22. package/esm/locale/el.es.js +7 -5
  23. package/esm/locale/el.mjs +7 -5
  24. package/esm/locale/en.es.js +3 -2
  25. package/esm/locale/en.mjs +3 -2
  26. package/esm/locale/es.es.js +1 -1
  27. package/esm/locale/es.mjs +1 -1
  28. package/esm/locale/fa.es.js +1 -1
  29. package/esm/locale/fa.mjs +1 -1
  30. package/esm/locale/fr.es.js +1 -1
  31. package/esm/locale/fr.mjs +1 -1
  32. package/esm/locale/hi.es.js +1 -1
  33. package/esm/locale/hi.mjs +1 -1
  34. package/esm/locale/hu.es.js +1 -1
  35. package/esm/locale/hu.mjs +1 -1
  36. package/esm/locale/id.es.js +1 -1
  37. package/esm/locale/id.mjs +1 -1
  38. package/esm/locale/it.es.js +1 -1
  39. package/esm/locale/it.mjs +1 -1
  40. package/esm/locale/ja.es.js +1 -1
  41. package/esm/locale/ja.mjs +1 -1
  42. package/esm/locale/jv.es.js +1 -1
  43. package/esm/locale/jv.mjs +1 -1
  44. package/esm/locale/ko.es.js +1 -1
  45. package/esm/locale/ko.mjs +1 -1
  46. package/esm/locale/my.es.js +1 -1
  47. package/esm/locale/my.mjs +1 -1
  48. package/esm/locale/nl.es.js +7 -5
  49. package/esm/locale/nl.mjs +7 -5
  50. package/esm/locale/pa-in.es.js +1 -1
  51. package/esm/locale/pa-in.mjs +1 -1
  52. package/esm/locale/pl.es.js +7 -5
  53. package/esm/locale/pl.mjs +7 -5
  54. package/esm/locale/pt.es.js +1 -1
  55. package/esm/locale/pt.mjs +1 -1
  56. package/esm/locale/ro.es.js +1 -1
  57. package/esm/locale/ro.mjs +1 -1
  58. package/esm/locale/ru.es.js +1 -1
  59. package/esm/locale/ru.mjs +1 -1
  60. package/esm/locale/rw.es.js +1 -1
  61. package/esm/locale/rw.mjs +1 -1
  62. package/esm/locale/sr.es.js +1 -1
  63. package/esm/locale/sr.mjs +1 -1
  64. package/esm/locale/sv.es.js +22 -0
  65. package/esm/locale/sv.mjs +22 -0
  66. package/esm/locale/th.es.js +1 -1
  67. package/esm/locale/th.mjs +1 -1
  68. package/esm/locale/tr.es.js +1 -1
  69. package/esm/locale/tr.mjs +1 -1
  70. package/esm/locale/uk.es.js +10 -8
  71. package/esm/locale/uk.mjs +10 -8
  72. package/esm/locale/uz.es.js +1 -1
  73. package/esm/locale/uz.mjs +1 -1
  74. package/esm/locale/vi.es.js +1 -1
  75. package/esm/locale/vi.mjs +1 -1
  76. package/esm/locale/zh-cn.es.js +1 -1
  77. package/esm/locale/zh-cn.mjs +1 -1
  78. package/esm/locale/zh-tw.es.js +1 -1
  79. package/esm/locale/zh-tw.mjs +1 -1
  80. package/esm/plugin/day-of-week.es.js +1 -1
  81. package/esm/plugin/day-of-week.mjs +1 -1
  82. package/esm/plugin/meridiem.es.js +20 -11
  83. package/esm/plugin/meridiem.mjs +20 -11
  84. package/esm/plugin/microsecond.es.js +1 -1
  85. package/esm/plugin/microsecond.mjs +1 -1
  86. package/esm/plugin/ordinal.es.js +1 -1
  87. package/esm/plugin/ordinal.mjs +1 -1
  88. package/esm/plugin/timespan.es.js +1 -1
  89. package/esm/plugin/timespan.mjs +1 -1
  90. package/esm/plugin/timezone.es.js +73 -0
  91. package/esm/plugin/timezone.mjs +73 -0
  92. package/esm/plugin/two-digit-year.es.js +1 -6
  93. package/esm/plugin/two-digit-year.mjs +1 -6
  94. package/locale/ar.js +2 -2
  95. package/locale/az.js +2 -2
  96. package/locale/bn.js +2 -2
  97. package/locale/cs.js +2 -2
  98. package/locale/de.js +2 -2
  99. package/locale/dk.js +2 -2
  100. package/locale/el.js +8 -6
  101. package/locale/en.js +4 -3
  102. package/locale/es.js +2 -2
  103. package/locale/fa.js +2 -2
  104. package/locale/fr.js +2 -2
  105. package/locale/hi.js +2 -2
  106. package/locale/hu.js +2 -2
  107. package/locale/id.js +2 -2
  108. package/locale/it.js +2 -2
  109. package/locale/ja.js +2 -2
  110. package/locale/jv.js +2 -2
  111. package/locale/ko.js +2 -2
  112. package/locale/my.js +2 -2
  113. package/locale/nl.js +8 -6
  114. package/locale/pa-in.js +3 -3
  115. package/locale/pl.js +8 -6
  116. package/locale/pt.js +2 -2
  117. package/locale/ro.js +2 -2
  118. package/locale/ru.js +2 -2
  119. package/locale/rw.js +2 -2
  120. package/locale/sr.js +2 -2
  121. package/locale/sv.js +30 -0
  122. package/locale/th.js +2 -2
  123. package/locale/tr.js +2 -2
  124. package/locale/uk.js +11 -9
  125. package/locale/uz.js +2 -2
  126. package/locale/vi.js +2 -2
  127. package/locale/zh-cn.js +3 -3
  128. package/locale/zh-tw.js +3 -3
  129. package/package.json +5 -5
  130. package/plugin/day-of-week.js +3 -3
  131. package/plugin/meridiem.js +21 -12
  132. package/plugin/microsecond.js +2 -2
  133. package/plugin/ordinal.js +2 -2
  134. package/plugin/timespan.js +2 -2
  135. package/plugin/timezone.js +81 -0
  136. package/plugin/two-digit-year.js +3 -8
package/EXTEND.md CHANGED
@@ -23,12 +23,26 @@ Tokens in this library have the following rules:
23
23
  'Eee' // Not good
24
24
  ```
25
25
 
26
- - To the parser, it is not able to add token of new alphabet.
26
+ - Only tokens consisting of the following alphabets can be added to the parser.
27
27
 
28
28
  ```javascript
29
- 'EEE' // This is not able to add because `E` is not an existing token in the parser.
30
- 'YYY' // This is OK because `Y` token is existing in the parser.
31
- 'SSS' // This is modifying, not adding. Because exactly the same token is existing.
29
+ 'Y' // Year
30
+ 'M' // Month
31
+ 'D' // Day
32
+ 'H' // 24-hour
33
+ 'A' // AM PM
34
+ 'h' // 12-hour
35
+ 's' // Second
36
+ 'S' // Millisecond
37
+ 'Z' // Timezone offset
38
+ ```
39
+
40
+ - Existing tokens cannot be overwritten.
41
+
42
+ ```javascript
43
+ 'YYY' // This is OK because the same token does not exists.
44
+ 'SSS' // This cannot be added because the exact same token exists.
45
+ 'EEE' // This is OK for the formatter, but cannot be added to the parser.
32
46
  ```
33
47
 
34
48
  ## Examples
@@ -61,12 +75,12 @@ date.extend({
61
75
 
62
76
  ### Example 2
63
77
 
64
- In the parser, modify `MMM` token to ignore case:
78
+ Add `MMMMM` token to the parser. This token ignores case:
65
79
 
66
80
  ```javascript
67
- date.parse('Dec 25 2019', 'MMM DD YYYY'); // => December 25, 2019
68
- date.parse('dec 25 2019', 'MMM DD YYYY'); // => December 25, 2019
69
- date.parse('DEC 25 2019', 'MMM DD YYYY'); // => December 25, 2019
81
+ date.parse('Dec 25 2019', 'MMMMM DD YYYY'); // => December 25, 2019
82
+ date.parse('dec 25 2019', 'MMMMM DD YYYY'); // => December 25, 2019
83
+ date.parse('DEC 25 2019', 'MMMMM DD YYYY'); // => December 25, 2019
70
84
  ```
71
85
 
72
86
  Source code example is here:
@@ -76,7 +90,7 @@ const date = require('date-and-time');
76
90
 
77
91
  date.extend({
78
92
  parser: {
79
- MMM: function (str) {
93
+ MMMMM: function (str) {
80
94
  const mmm = this.res.MMM.map(m => m.toLowerCase());
81
95
  const result = this.find(mmm, str.toLowerCase());
82
96
  result.value++;
@@ -86,4 +100,8 @@ date.extend({
86
100
  });
87
101
  ```
88
102
 
89
- Modifying the parser may be a bit difficult. Refer to the library source code to grasp the default behavior.
103
+ Extending the parser may be a bit difficult. Refer to the library source code to grasp the default behavior.
104
+
105
+ ## Caveats
106
+
107
+ Note that switching locales or applying plugins after extending the library will be cleared all extensions. In such cases, you need to extend the library again.
package/LOCALE.md CHANGED
@@ -94,6 +94,7 @@ Romanian (ro)
94
94
  Russian (ru)
95
95
  Serbian (sr)
96
96
  Spanish (es)
97
+ Swedish (sv)
97
98
  Thai (th)
98
99
  Turkish (tr)
99
100
  Ukrainian (uk)
package/PLUGINS.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Plugins
2
2
 
3
- This library is oriented towards minimalism, so it may appear to be lacking in features. Plugin is the most realistic solution to such dissatisfaction. By importing plugins, you can extend the functionality of this library, mainly formatter and parser.
3
+ This library is oriented towards minimalism, so it may seem to some developers to be lacking in features. Plugin is the most realistic solution to such dissatisfaction. By importing plugins, you can extend the functionality of this library, mainly a formatter and a parser.
4
+
5
+ *The formatter is used in `format()`, etc., the parser is used in `parse()`, `preparse()`, `isValid()`, etc.*
4
6
 
5
7
  ## Usage
6
8
 
@@ -52,41 +54,50 @@ date.plugin('foobar');
52
54
  </script>
53
55
  ```
54
56
 
55
- ### NOTE
57
+ ### Note
56
58
 
57
59
  - If you want to use ES Modules in Node.js without a transpiler, you need to add `"type": "module"` in your `package.json` or change your file extension from `.js` to `.mjs`.
58
60
 
59
61
  ## Plugin List
60
62
 
61
63
  - [day-of-week](#day-of-week)
62
- - It adds day of week notation to the parser.
64
+ - It adds *"dummy"* tokens for `day of week` to the parser.
63
65
 
64
66
  - [meridiem](#meridiem)
65
- - It extends `A` token.
67
+ - It adds various notations for `AM PM`.
66
68
 
67
69
  - [microsecond](#microsecond)
68
- - It adds microsecond notation to the parser.
70
+ - It adds tokens for microsecond to the parser.
69
71
 
70
72
  - [ordinal](#ordinal)
71
73
  - It adds ordinal notation of date to the formatter.
72
74
 
73
75
  - [timespan](#timespan)
74
- - It adds `timeSpan()` function to the library.
76
+ - It adds `timeSpan()` function that calculates the difference of two dates to the library.
77
+
78
+ - [timezone](#timezone)
79
+ - It adds `formatTZ()` and `parseTZ()` functions that support `IANA time zone names` to the library.
75
80
 
76
81
  - [two-digit-year](#two-digit-year)
77
82
  - It adds two-digit year notation to the parser.
78
83
 
79
- ## Plugin Details
84
+ ---
80
85
 
81
86
  ### day-of-week
82
87
 
83
- It adds `dddd`, `ddd` and `dd` tokens to the parser. While these meanings are as follows, in fact they don't make sense because day of week doesn't include information to determine a date:
88
+ It adds tokens for `day of week` to the parser. Although `day of week` is not significant information for the parser to identify a date, these tokens are sometimes useful. For example, when a string to be parsed contains a day of week, and you just want to skip it.
89
+
90
+ **formatter:**
91
+
92
+ There is no change.
84
93
 
85
- | token | meaning | examples of acceptable form | added or modified |
86
- |:------|:-------------------------|:----------------------------|:------------------|
87
- | dddd | day of week (long) | Friday, Sunday | |
88
- | ddd | day of week (short) | Fri, Sun | ✔ |
89
- | dd | day of week (very short) | Fr, Su | ✔ |
94
+ **parser:**
95
+
96
+ | token | meaning | acceptable examples |
97
+ |:------|:-----------|:--------------------|
98
+ | dddd | long | Friday, Sunday |
99
+ | ddd | short | Fri, Sun |
100
+ | dd | very short | Fr, Su |
90
101
 
91
102
  ```javascript
92
103
  const date = require('date-and-time');
@@ -103,22 +114,27 @@ date.parse('Thursday, March 05, 2020', ' , MMMM, D YYYY');
103
114
  date.parse('Friday, March 06, 2020', ' , MMMM, D YYYY');
104
115
  ```
105
116
 
117
+ ---
118
+
106
119
  ### meridiem
107
120
 
108
- It adds `AA`, `a` and `aa` tokens to the formatter. These meanings are as follows:
121
+ It adds various notations for AM PM.
109
122
 
110
- | token | meaning | examples of output | added or modified |
111
- |:------|:-----------------------------------|:-------------------|:------------------|
112
- | A | meridiem (uppercase) | AM, PM | |
113
- | AA | meridiem (uppercase with ellipsis) | A.M., P.M. | ✔ |
114
- | a | meridiem (lowercase) | am, pm | ✔ |
115
- | aa | meridiem (lowercase with ellipsis) | a.m., p.m. | ✔ |
123
+ **formatter:**
116
124
 
117
- It also extends `A` token of the parser as follows:
125
+ | token | meaning | output examples |
126
+ |:------|:------------------------|:----------------|
127
+ | AA | uppercase with ellipsis | A.M., P.M. |
128
+ | a | lowercase | am, pm |
129
+ | aa | lowercase with ellipsis | a.m., p.m. |
118
130
 
119
- | token | meaning | examples of acceptable form | added or modified |
120
- |:------|:---------------------------------|:---------------------------------------|:------------------|
121
- | A | all the above notations | AM, PM, A.M., P.M., am, pm, a.m., p.m. | ✔ |
131
+ **parser:**
132
+
133
+ | token | meaning | acceptable examples |
134
+ |:------|:------------------------|:--------------------|
135
+ | AA | uppercase with ellipsis | A.M., P.M. |
136
+ | a | lowercase | am, pm |
137
+ | aa | lowercase with ellipsis | a.m., p.m. |
122
138
 
123
139
  ```javascript
124
140
  const date = require('date-and-time');
@@ -136,25 +152,34 @@ date.format(new Date(), 'hh:mm AA'); // => '12:34 P.M.'
136
152
  date.format(new Date(), 'hh:mm a'); // => '12:34 pm'
137
153
  date.format(new Date(), 'hh:mm aa'); // => '12:34 p.m.'
138
154
 
139
- // The parser will be acceptable all the above notations with only `A` token.
155
+ // This is default behavior of the parser.
140
156
  date.parse('12:34 PM', 'hh:mm A'); // => Jan 1 1970 12:34:00
141
- date.parse('12:34 P.M.', 'hh:mm A'); // => Jan 1 1970 12:34:00
142
- date.parse('12:34 pm', 'hh:mm A'); // => Jan 1 1970 12:34:00
143
- date.parse('12:34 p.m.', 'hh:mm A'); // => Jan 1 1970 12:34:00
157
+
158
+ // These are added tokens to the parser.
159
+ date.parse('12:34 P.M.', 'hh:mm AA'); // => Jan 1 1970 12:34:00
160
+ date.parse('12:34 pm', 'hh:mm a'); // => Jan 1 1970 12:34:00
161
+ date.parse('12:34 p.m.', 'hh:mm aa'); // => Jan 1 1970 12:34:00
144
162
  ```
145
163
 
164
+ This plugin has a **breaking change**. In previous versions, the `A` token for the parser could parse various notations for AM PM, but in the new version, it can only parse `AM` and `PM`. For other notations, a dedicated token is now provided for each.
165
+
166
+ ---
167
+
146
168
  ### microsecond
147
169
 
148
- It adds `SSSSSS`, `SSSSS` and `SSSS` tokens to the parser. Thease meanings are as follows:
170
+ It adds tokens for microsecond to the parser. If a time string to be parsed contains microsecond, these tokens are useful. In JS, however, it is not supported microsecond accuracy, a parsed value is rounded to millisecond accuracy.
171
+
172
+ **formatter:**
173
+
174
+ There is no change.
149
175
 
150
- | token | meaning | examples of output | added or modified |
151
- |:-------|:------------------------------|:-------------------|:------------------|
152
- | SSSSSS | microsecond (high accuracy) | 753123, 022113 | |
153
- | SSSSS | microsecond (middle accuracy) | 75312, 02211 | ✔ |
154
- | SSSS | microsecond (low accuracy) | 7531, 0221 | ✔ |
155
- | SSS | millisecond (high accuracy) | 753, 022 | |
156
- | SS | millisecond (middle accuracy) | 75, 02 | |
157
- | S | millisecond (low accuracy) | 7, 0 | |
176
+ **parser:**
177
+
178
+ | token | meaning | acceptable examples |
179
+ |:-------|:----------------|:--------------------|
180
+ | SSSSSS | high accuracy | 753123, 022113 |
181
+ | SSSSS | middle accuracy | 75312, 02211 |
182
+ | SSSS | low accuracy | 7531, 0221 |
158
183
 
159
184
  ```javascript
160
185
  const date = require('date-and-time');
@@ -164,7 +189,7 @@ const microsecond = require('date-and-time/plugin/microsecond');
164
189
  // Apply "microsecond" plugin to the library.
165
190
  date.plugin(microsecond);
166
191
 
167
- // A date object in JavaScript supports `millisecond` (ms):
192
+ // A date object in JavaScript supports `millisecond` (ms) like this:
168
193
  date.parse('12:34:56.123', 'HH:mm:ss.SSS');
169
194
 
170
195
  // 4 or more digits number sometimes seen is not `millisecond`, probably `microsecond` (μs):
@@ -173,15 +198,21 @@ date.parse('12:34:56.123456', 'HH:mm:ss.SSSSSS');
173
198
  // 123456µs will be rounded to 123ms.
174
199
  ```
175
200
 
201
+ ---
202
+
176
203
  ### ordinal
177
204
 
178
- It adds `DDD` token to the formatter. This meaning is as follows:
205
+ It adds `DDD` token that output ordinal notation of date to the formatter.
206
+
207
+ **formatter:**
179
208
 
180
- | token | meaning | examples of output | added or modified |
181
- |:------|:-------------------------|:--------------------|:------------------|
182
- | DDD | ordinal notation of date | 1st, 2nd, 3rd, 31th | ✔ |
183
- | DD | date with zero-padding | 01, 02, 03, 31 | |
184
- | D | date | 1, 2, 3, 31 | |
209
+ | token | meaning | output examples |
210
+ |:------|:-------------------------|:--------------------|
211
+ | DDD | ordinal notation of date | 1st, 2nd, 3rd, 31th |
212
+
213
+ **parser:**
214
+
215
+ There is no change.
185
216
 
186
217
  ```javascript
187
218
  const date = require('date-and-time');
@@ -199,9 +230,17 @@ date.format(new Date(), 'MMM DD YYYY'); // => Jan 01 2019
199
230
  date.format(new Date(), 'MMM DDD YYYY'); // => Jan 1st 2019
200
231
  ```
201
232
 
233
+ ---
234
+
202
235
  ### timespan
203
236
 
204
- It adds `timeSpan()` function to the library. This function is similar to the `subtract()`, but this can display a formatted elapsed time between two date objects:
237
+ It adds `timeSpan()` function that calculates the difference of two dates to the library. This function is similar to `subtract()`, the difference is that it can format the calculation results.
238
+
239
+ #### timeSpan(date1, date2)
240
+
241
+ - @param {**Date**} date1 - a Date object
242
+ - @param {**Date**} date2 - a Date object
243
+ - @returns {**Object**} a result object subtracting date2 from date1
205
244
 
206
245
  ```javascript
207
246
  const date = require('date-and-time');
@@ -219,7 +258,7 @@ date.timeSpan(now, new_years_day).toHours('H [hours] m [minutes] s [seconds]');
219
258
  date.timeSpan(now, new_years_day).toMinutes('mmmmmmmmmm [minutes]'); // => '0000092222 minutes'
220
259
  ```
221
260
 
222
- The `timeSpan()` returns an object that has some functions as with the `subtract()`:
261
+ Like `subtract()`, `timeSpan()` returns an object with functions like this:
223
262
 
224
263
  | function | description |
225
264
  |:---------------|:------------------------|
@@ -229,7 +268,7 @@ The `timeSpan()` returns an object that has some functions as with the `subtract
229
268
  | toSeconds | Outputs as seconds |
230
269
  | toMilliseconds | Outputs as milliseconds |
231
270
 
232
- Available tokens in those functions and their meanings are as follows:
271
+ In these functions can be available some tokens to format the calculation result. Here are the tokens and their meanings:
233
272
 
234
273
  | function | available tokens |
235
274
  |:---------------|:-----------------|
@@ -247,36 +286,119 @@ Available tokens in those functions and their meanings are as follows:
247
286
  | s | second |
248
287
  | S | millisecond |
249
288
 
289
+ ---
290
+
291
+ ### timezone
292
+
293
+ It adds `formatTZ()` and `parseTZ()` functions that support `IANA time zone names` (`America/Los_Angeles`, `Asia/Tokyo`, and so on) to the library.
294
+
295
+ #### formatTZ(dateObj, arg[, timeZone])
296
+
297
+ - @param {**Date**} dateObj - a Date object
298
+ - @param {**string|Array.\<string\>**} arg - a format string or its compiled object
299
+ - @param {**string**} [timeZone] - output as this time zone
300
+ - @returns {**string**} a formatted string
301
+
302
+ The `formatTZ()` is upward compatible with `format()`. Tokens available here are the same as for the `format()`. If the `timeZone` is omitted, it output the date string with local time zone.
303
+
304
+ #### parseTZ(dateString, arg[, timeZone])
305
+
306
+ - @param {**string**} dateString - a date string
307
+ - @param {**string|Array.\<string\>**} arg - a format string or its compiled object
308
+ - @param {**string**} [timeZone] - input as this time zone
309
+ - @returns {**Date**} a constructed date
310
+
311
+ The `parseTZ()` is upward compatible with `parse()`. Tokens available here are the same as for the `parse()`. If the `timeZone` is omitted, the time zone of the date string is assumed to be local time zone.
312
+
313
+ ```javascript
314
+ const date = require('date-and-time');
315
+ // Import "timezone" plugin.
316
+ const timezone = require('date-and-time/plugin/timezone');
317
+
318
+ // Apply "timezone" plugin to the library.
319
+ date.plugin(timezone);
320
+
321
+ const d1 = new Date(Date.UTC(2021, 2, 14, 9, 59, 59, 999)); // 2021-03-14T09:59:59.999Z
322
+ date.formatTZ(d1, 'MMMM DD YYYY H:mm:ss.SSS [UTC]Z', 'America/Los_Angeles'); // March 14 2021 1:59:59.999 UTC-0800
323
+
324
+ const d2 = new Date(Date.UTC(2021, 2, 14, 10, 0, 0, 0)); // 2021-03-14T10:00:00.000Z
325
+ date.formatTZ(d2, 'MMMM DD YYYY H:mm:ss.SSS [UTC]Z', 'America/Los_Angeles'); // March 14 2021 3:00:00.000 UTC-0700
326
+
327
+ // Parses the date string assuming that the time zone is "Pacific/Honolulu" (UTC-1000).
328
+ date.parseTZ('Sep 25 2021 4:00:00', 'MMM D YYYY H:mm:ss', 'Pacific/Honolulu'); // 2021-09-25T14:00:00.000Z
329
+
330
+ // Parses the date string assuming that the time zone is "Europe/London" (UTC+0100).
331
+ date.parseTZ('Sep 25 2021 4:00:00', 'MMM D YYYY H:mm:ss', 'Europe/London'); // 2021-09-25T03:00:00.000Z
332
+ ```
333
+
334
+ #### Caveats
335
+
336
+ - This plugin uses the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) object to parse `IANA time zone names`. Note that if you use this plugin in older browsers, this may **NOT** be supported there. At least it does not work in IE.
337
+ - If you don't need to use `IANA time zone names`, you should not use this plugin for performance reasons. The `format()` and the `parse()` are enough.
338
+
339
+ #### Start of DST (Daylight Saving Time)
340
+
341
+ For example, in the US, when local standard time is about to reach Sunday, 14 March 2021, `02:00:00` clocks are turned `forward` 1 hour to Sunday, 14 March 2021, `03:00:00` local daylight time instead. Thus, there is no `02:00:00` to `02:59:59` on 14 March 2021. In such edge cases, the `parseTZ()` will parse like this:
342
+
343
+ ```javascript
344
+ date.parseTZ('Mar 14 2021 1:59:59', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => 2021-03-14T09:59:59Z
345
+ date.parseTZ('Mar 14 2021 2:00:00', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => NaN
346
+ date.parseTZ('Mar 14 2021 2:59:59', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => NaN
347
+ date.parseTZ('Mar 14 2021 3:00:00', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => 2021-03-14T10:00:00Z
348
+ ```
349
+
350
+ #### End of DST
351
+
352
+ Also, when local daylight time is about to reach Sunday, 7 November 2021, `02:00:00` clocks are turned `backward` 1 hour to Sunday, 7 November 2021, `01:00:00` local standard time instead. Thus, `01:00:00` to `01:59:59` on November 7 2021 is repeated twice. Since there are two possible times between them, DST or not, the `parseTZ()` assumes that the time is former to make the result unique:
353
+
354
+ ```javascript
355
+ // The parseTZ() assumes that this time is DST.
356
+ date.parseTZ('Nov 7 2021 1:59:59', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => 2021-11-07T08:59:59Z
357
+ // This time is already PST.
358
+ date.parseTZ('Nov 7 2021 2:00:00', 'MMM D YYYY H:mm:ss', 'America/Los_Angeles'); // => 2021-11-07T10:00:00Z
359
+ ```
360
+
361
+ At the first example above, if you want the parser to parse the time as PST (Pacific Standard Time), use the `parse()` with a time offset instead:
362
+
363
+ ```javascript
364
+ date.parse('Nov 7 2021 1:59:59 -0800', 'MMM D YYYY H:mm:ss Z'); // => 2021-11-07T09:59:59Z
365
+ ```
366
+
367
+ ---
368
+
250
369
  ### two-digit-year
251
370
 
252
- It adds `YY` token to the parser and also changes behavior of `Y` token. These meanings are as follows:
371
+ It adds `YY` token to the parser. This token will convert the year 69 or earlier to 2000s, the year 70 or later to 1900s. In brief:
372
+
373
+ | examples | result |
374
+ |:------------------------|:-------|
375
+ | 00, 01, 02, ..., 68, 69 | 2000s |
376
+ | 70, 71, 72, ..., 98, 99 | 1900s |
377
+
378
+ **formatter:**
253
379
 
254
- | token | meaning | examples of acceptable form | added or modified |
255
- |:------|:------------------------------------|:----------------------------|:------------------|
256
- | YYYY | four-digit year | 2019, 0123, 0001 | |
257
- | YY | two-digit year | 90, 00, 08, 19 | ✔ |
258
- | Y | two-digit year without zero-padding | 90, 0, 8, 19 | ✔ |
380
+ There is no change.
259
381
 
260
- `YY` and `Y` token will convert the year 69 or earlier to 2000s, the year 70 or later to 1900s. By this change, `Y` token will no longer acceptable the year 100 or later, so use `YYYY` token instead if necessary.
382
+ **parser:**
383
+
384
+ | token | meaning | acceptable examples |
385
+ |:------|:---------------|:--------------------|
386
+ | YY | two-digit year | 90, 00, 08, 19 |
261
387
 
262
388
  ```javascript
263
389
  const date = require('date-and-time');
264
390
  // Import "two-digit-year" plugin as a named "two_digit_year".
265
391
  const two_digit_year = require('date-and-time/plugin/two-digit-year');
266
392
 
267
- // These are default behavior of the parser.
393
+ // This is the default behavior of the parser.
268
394
  date.parse('Dec 25 69', 'MMM D YY'); // => Invalid Date
269
- date.parse('Dec 25 70', 'MMM D Y'); // => 70 AD (ancient times)
270
395
 
271
396
  // Apply the "two_digit_year" plugin to the library.
272
397
  date.plugin(two_digit_year);
273
398
 
274
- // These convert the year 69 or earlier to 2000s, the year 70 or later to 1900s.
399
+ // The `YY` token convert the year 69 or earlier to 2000s, the year 70 or later to 1900s.
275
400
  date.parse('Dec 25 69', 'MMM D YY'); // => Dec 25 2069
276
- date.parse('Dec 25 70', 'MMM D Y'); // => Dec 25 1970
277
-
278
- // `Y` token will no longer acceptable the year 100 or later.
279
- date.parse('Dec 25 2019', 'MMM D Y'); // => Invalid Date
280
- // Use `YYYY` token instead if necessary.
281
- date.parse('Dec 25 2019', 'MMM D YYYY'); // => Dec 25 2019
401
+ date.parse('Dec 25 70', 'MMM D YY'); // => Dec 25 1970
282
402
  ```
403
+
404
+ This plugin has a **breaking change**. In previous versions, this plugin overrode the default behavior of the `Y` token, but this has been obsolete.
package/README.md CHANGED
@@ -24,16 +24,30 @@ npm i date-and-time
24
24
 
25
25
  ## Recent Changes
26
26
 
27
- - 1.0.1
27
+ - 2.1.1
28
28
  - Updated dev dependencies to resolve vulnerability.
29
29
 
30
- - 1.0.0
31
- - **First stable release!**
32
- - ES Modules support.
33
- - Added Kinyarwanda support.
30
+ - 2.1.0
31
+ - Fixed an issue that the lib's functions assigned to variables using ES6 destructuring assignment cause an error.
34
32
 
35
- - 0.14.2
36
- - Fixed regular expression denial of service (ReDoS) vulnerability.
33
+ ```javascript
34
+ // Destructuring assignment
35
+ const { format, parse } = require('date-and-time');
36
+
37
+ // These used to be errors in 2.0.x.
38
+ format(new Date(), 'MMM DD YYYY');
39
+ parse('Jan 11 2022', 'MMM DD YYYY');
40
+ ```
41
+
42
+ - Added Swedish support.
43
+
44
+ - 2.0.1
45
+ - Fixed a bug that the timezone plugin does not support changing locales.
46
+
47
+ - 2.0.0
48
+ - Fixed a conflict when importing multiple plugins and locales.
49
+ - **Breaking Changes!** Due to the above fix, the specifications of plugin, locale, and extension have been changed. The `meridiem` plugin and the `two-digit-year` plugin are now partially incompatible with previous ones. See [here](./PLUGINS.md) for details. Also the `extend()` function has changed. If you are using it, check [here](./EXTEND.md) for any impact. The locales are still compatible.
50
+ - Added `timezone` plugin. You can now use the IANA timezone name to output a datetime string or input a date object. See [PLUGINS.md](./PLUGINS.md) for details.
37
51
 
38
52
  ## Usage
39
53
 
@@ -69,7 +83,7 @@ import date from '/path/to/date-and-time.es.min.js';
69
83
 
70
84
  ## API
71
85
 
72
- - [format](#formatdateobj-formatstring-utc)
86
+ - [format](#formatdateobj-arg-utc)
73
87
  - Formatting a Date and Time (Date -> String)
74
88
 
75
89
  - [parse](#parsedatestring-arg-utc)
@@ -126,7 +140,7 @@ import date from '/path/to/date-and-time.es.min.js';
126
140
  - [plugin](#pluginname-plugin)
127
141
  - Importing or defining plugins
128
142
 
129
- ### format(dateObj, formatString[, utc])
143
+ ### format(dateObj, arg[, utc])
130
144
 
131
145
  - @param {**Date**} dateObj - a Date object
132
146
  - @param {**string|Array.\<string\>**} arg - a format string or its compiled object
@@ -207,7 +221,7 @@ You can also define your own tokens. See [EXTEND.md](./EXTEND.md) for details.
207
221
 
208
222
  ### parse(dateString, arg[, utc])
209
223
 
210
- - @param {string} dateString - a date string
224
+ - @param {**string**} dateString - a date string
211
225
  - @param {**string|Array.\<string\>**} arg - a format string or its compiled object
212
226
  - @param {**boolean**} [utc] - input as UTC
213
227
  - @returns {**Date**} a constructed date
@@ -224,43 +238,44 @@ date.parse('Feb 29 2017', 'MMM D YYYY'); // => Invalid Date
224
238
 
225
239
  Available tokens and their meanings are as follows:
226
240
 
227
- | token | meaning | examples of acceptable form |
228
- |:-------|:-------------------------------------|:---------------------------------------|
229
- | YYYY | four-digit year | 0999, 2015 |
230
- | Y | four-digit year without zero-padding | 2, 44, 88, 2015 |
231
- | MMMM | month name (long) | January, December |
232
- | MMM | month name (short) | Jan, Dec |
233
- | MM | month with zero-padding | 01, 12 |
234
- | M | month | 1, 12 |
235
- | DD | date with zero-padding | 02, 31 |
236
- | D | date | 2, 31 |
237
- | HH | 24-hour with zero-padding | 23, 08 |
238
- | H | 24-hour | 23, 8 |
239
- | hh | 12-hour with zero-padding | 11, 08 |
240
- | h | 12-hour | 11, 8 |
241
- | A | meridiem (uppercase) | AM, PM |
242
- | mm | minute with zero-padding | 14, 07 |
243
- | m | minute | 14, 7 |
244
- | ss | second with zero-padding | 05, 10 |
245
- | s | second | 5, 10 |
246
- | SSS | millisecond (high accuracy) | 753, 022 |
247
- | SS | millisecond (middle accuracy) | 75, 02 |
248
- | S | millisecond (low accuracy) | 7, 0 |
249
- | Z | timezone offset | +0100, -0800 |
241
+ | token | meaning | examples of acceptable form |
242
+ |:-------|:-------------------------------------|:----------------------------|
243
+ | YYYY | four-digit year | 0999, 2015 |
244
+ | Y | four-digit year without zero-padding | 2, 44, 88, 2015 |
245
+ | MMMM | month name (long) | January, December |
246
+ | MMM | month name (short) | Jan, Dec |
247
+ | MM | month with zero-padding | 01, 12 |
248
+ | M | month | 1, 12 |
249
+ | DD | date with zero-padding | 02, 31 |
250
+ | D | date | 2, 31 |
251
+ | HH | 24-hour with zero-padding | 23, 08 |
252
+ | H | 24-hour | 23, 8 |
253
+ | hh | 12-hour with zero-padding | 11, 08 |
254
+ | h | 12-hour | 11, 8 |
255
+ | A | meridiem (uppercase) | AM, PM |
256
+ | mm | minute with zero-padding | 14, 07 |
257
+ | m | minute | 14, 7 |
258
+ | ss | second with zero-padding | 05, 10 |
259
+ | s | second | 5, 10 |
260
+ | SSS | millisecond (high accuracy) | 753, 022 |
261
+ | SS | millisecond (middle accuracy) | 75, 02 |
262
+ | S | millisecond (low accuracy) | 7, 0 |
263
+ | Z | timezone offset | +0100, -0800 |
250
264
 
251
265
  You can also use the following tokens by importing plugins. See [PLUGINS.md](./PLUGINS.md) for details.
252
266
 
253
- | token | meaning | examples of acceptable form |
254
- |:-------|:-------------------------------------|:---------------------------------------|
255
- | YY | two-digit year | 90, 00, 08, 19 |
256
- | Y | two-digit year without zero-padding | 90, 0, 8, 19 |
257
- | A | meridiem | AM, PM, A.M., P.M., am, pm, a.m., p.m. |
258
- | dddd | day of week (long) | Friday, Sunday |
259
- | ddd | day of week (short) | Fri, Sun |
260
- | dd | day of week (very short) | Fr, Su |
261
- | SSSSSS | microsecond (high accuracy) | 123456, 000001 |
262
- | SSSSS | microsecond (middle accuracy) | 12345, 00001 |
263
- | SSSS | microsecond (low accuracy) | 1234, 0001 |
267
+ | token | meaning | examples of acceptable form |
268
+ |:-------|:-------------------------------------|:----------------------------|
269
+ | YY | two-digit year | 90, 00, 08, 19 |
270
+ | AA | meridiem (uppercase with ellipsis) | A.M., P.M. |
271
+ | a | meridiem (lowercase) | am, pm |
272
+ | aa | meridiem (lowercase with ellipsis) | a.m., p.m. |
273
+ | dddd | day of week (long) | Friday, Sunday |
274
+ | ddd | day of week (short) | Fri, Sun |
275
+ | dd | day of week (very short) | Fr, Su |
276
+ | SSSSSS | microsecond (high accuracy) | 123456, 000001 |
277
+ | SSSSS | microsecond (middle accuracy) | 12345, 00001 |
278
+ | SSSS | microsecond (low accuracy) | 1234, 0001 |
264
279
 
265
280
  #### Note 1. Invalid Date
266
281
 
@@ -569,7 +584,7 @@ See [LOCALE.md](./LOCALE.md) for details.
569
584
  - @param {**Object**} extension - extension object
570
585
  - @returns {**void**}
571
586
 
572
- It extends the formatter and the parser of the current locale. See [EXTEND.md](./EXTEND.md) for details.
587
+ It extends this library. See [EXTEND.md](./EXTEND.md) for details.
573
588
 
574
589
  ### plugin(name[, plugin])
575
590
 
@@ -577,7 +592,7 @@ It extends the formatter and the parser of the current locale. See [EXTEND.md](.
577
592
  - @param {**Object**} [plugin] - plugin object
578
593
  - @returns {**void**}
579
594
 
580
- Plugin is a named extension object. By installing predefined plugins, you can easily extend the formatter and the parser of the current locale. See [PLUGINS.md](./PLUGINS.md) for details.
595
+ Plugin is a named extension object. By installing predefined plugins, you can easily extend this library. See [PLUGINS.md](./PLUGINS.md) for details.
581
596
 
582
597
  ## Browser Support
583
598