@thi.ng/date 2.5.4 → 2.5.6
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.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +45 -55
- package/checks.js +8 -17
- package/datetime.js +318 -321
- package/duration.js +53 -97
- package/format.js +243 -388
- package/i18n/de.js +77 -81
- package/i18n/en.js +77 -81
- package/i18n/es.js +42 -43
- package/i18n/fr.js +44 -45
- package/i18n/it.js +44 -45
- package/i18n.js +47 -118
- package/internal/precision.js +6 -16
- package/iterators.js +41 -93
- package/package.json +9 -7
- package/relative.js +108 -168
- package/round.js +77 -124
- package/timecode.js +19 -43
- package/units.js +21 -16
package/datetime.js
CHANGED
|
@@ -1,330 +1,327 @@
|
|
|
1
1
|
import { isNumber } from "@thi.ng/checks/is-number";
|
|
2
2
|
import { isString } from "@thi.ng/checks/is-string";
|
|
3
3
|
import { Z2, Z3, Z4 } from "@thi.ng/strings/pad-left";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
DAY,
|
|
6
|
+
HOUR,
|
|
7
|
+
MINUTE,
|
|
8
|
+
SECOND
|
|
9
|
+
} from "./api.js";
|
|
5
10
|
import { ensureDate, ensureEpoch, isLeapYear } from "./checks.js";
|
|
6
11
|
import { defFormat } from "./format.js";
|
|
7
12
|
import { LOCALE } from "./i18n.js";
|
|
8
13
|
import { __precisionToID } from "./internal/precision.js";
|
|
9
14
|
import { dayInYear, daysInMonth, weekInYear } from "./units.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
y;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
315
|
-
valueOf() {
|
|
316
|
-
return this.getTime();
|
|
317
|
-
}
|
|
15
|
+
const dateTime = (epoch, prec) => new DateTime(epoch, prec);
|
|
16
|
+
class DateTime {
|
|
17
|
+
t;
|
|
18
|
+
s;
|
|
19
|
+
m;
|
|
20
|
+
h;
|
|
21
|
+
d;
|
|
22
|
+
M;
|
|
23
|
+
y;
|
|
24
|
+
constructor(epoch = Date.now(), prec = "t") {
|
|
25
|
+
const x = ensureDate(epoch);
|
|
26
|
+
const id = __precisionToID(prec);
|
|
27
|
+
this.y = x.getUTCFullYear();
|
|
28
|
+
this.M = id >= 1 ? x.getUTCMonth() : 0;
|
|
29
|
+
this.d = id >= 2 ? x.getUTCDate() : 1;
|
|
30
|
+
this.h = id >= 3 ? x.getUTCHours() : 0;
|
|
31
|
+
this.m = id >= 4 ? x.getUTCMinutes() : 0;
|
|
32
|
+
this.s = id >= 5 ? x.getUTCSeconds() : 0;
|
|
33
|
+
this.t = id >= 6 ? x.getUTCMilliseconds() : 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Readonly property, returning 1-based quarter
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* - 1 = Jan - Mar
|
|
40
|
+
* - 2 = Apr - Jun
|
|
41
|
+
* - 3 = Jul - Sep
|
|
42
|
+
* - 4 = Oct - Dec
|
|
43
|
+
*/
|
|
44
|
+
get q() {
|
|
45
|
+
return (this.M / 3 | 0) + 1;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Alias readonly property, same as {@link DateTime.weekInYear}.
|
|
49
|
+
*/
|
|
50
|
+
get w() {
|
|
51
|
+
return this.weekInYear();
|
|
52
|
+
}
|
|
53
|
+
set(d) {
|
|
54
|
+
const $d = ensureDateTime(d);
|
|
55
|
+
this.y = $d.y;
|
|
56
|
+
this.M = $d.M;
|
|
57
|
+
this.d = $d.d;
|
|
58
|
+
this.h = $d.h;
|
|
59
|
+
this.m = $d.m;
|
|
60
|
+
this.s = $d.s;
|
|
61
|
+
this.t = $d.t;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
copy() {
|
|
65
|
+
return new DateTime(this.toISOString());
|
|
66
|
+
}
|
|
67
|
+
getTime() {
|
|
68
|
+
return Date.UTC(this.y, this.M, this.d, this.h, this.m, this.s, this.t);
|
|
69
|
+
}
|
|
70
|
+
withPrecision(prec) {
|
|
71
|
+
return new DateTime(this, prec);
|
|
72
|
+
}
|
|
73
|
+
setPrecision(prec) {
|
|
74
|
+
const precID = __precisionToID(prec);
|
|
75
|
+
precID < 6 && (this.t = 0);
|
|
76
|
+
precID < 5 && (this.s = 0);
|
|
77
|
+
precID < 4 && (this.m = 0);
|
|
78
|
+
precID < 3 && (this.h = 0);
|
|
79
|
+
precID < 2 && (this.d = 1);
|
|
80
|
+
precID < 1 && (this.M = 0);
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
compare(d) {
|
|
84
|
+
return this.getTime() - ensureEpoch(d);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns true if this instance is before the given date, i.e. if
|
|
88
|
+
* `this.compare(d) < 0`.
|
|
89
|
+
*
|
|
90
|
+
* @param d -
|
|
91
|
+
*/
|
|
92
|
+
isBefore(d) {
|
|
93
|
+
return this.compare(d) < 0;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns true if this instance is before the given date, i.e. if
|
|
97
|
+
* `this.compare(d) > 0`.
|
|
98
|
+
*
|
|
99
|
+
* @param d -
|
|
100
|
+
*/
|
|
101
|
+
isAfter(d) {
|
|
102
|
+
return this.compare(d) > 0;
|
|
103
|
+
}
|
|
104
|
+
equiv(o) {
|
|
105
|
+
return maybeIsDate(o) ? this.compare(o) === 0 : false;
|
|
106
|
+
}
|
|
107
|
+
eqDelta(d, eps = 0) {
|
|
108
|
+
return Math.abs(this.getTime() - ensureDate(d).getTime()) <= eps;
|
|
109
|
+
}
|
|
110
|
+
daysInMonth() {
|
|
111
|
+
return daysInMonth(this.y, this.M);
|
|
112
|
+
}
|
|
113
|
+
dayInYear() {
|
|
114
|
+
return dayInYear(this.y, this.M, this.d);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Returns week number according to ISO8601.
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* Reference:
|
|
121
|
+
* https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
|
|
122
|
+
*
|
|
123
|
+
*/
|
|
124
|
+
weekInYear() {
|
|
125
|
+
return weekInYear(this.y, this.M, this.d);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Leap years are multiple of 4, excludingcentennial years that aren’t
|
|
129
|
+
* multiples of 400.
|
|
130
|
+
*/
|
|
131
|
+
isLeapYear() {
|
|
132
|
+
return isLeapYear(this.y);
|
|
133
|
+
}
|
|
134
|
+
incMillisecond() {
|
|
135
|
+
if (++this.t > 999) {
|
|
136
|
+
this.t = 0;
|
|
137
|
+
this.incSecond();
|
|
138
|
+
}
|
|
139
|
+
return this.t;
|
|
140
|
+
}
|
|
141
|
+
decMillisecond() {
|
|
142
|
+
if (--this.t < 0) {
|
|
143
|
+
this.t = 999;
|
|
144
|
+
this.decSecond();
|
|
145
|
+
}
|
|
146
|
+
return this.t;
|
|
147
|
+
}
|
|
148
|
+
incSecond() {
|
|
149
|
+
if (++this.s > 59) {
|
|
150
|
+
this.s = 0;
|
|
151
|
+
this.incMinute();
|
|
152
|
+
}
|
|
153
|
+
return this.s;
|
|
154
|
+
}
|
|
155
|
+
decSecond() {
|
|
156
|
+
if (--this.s < 0) {
|
|
157
|
+
this.s = 59;
|
|
158
|
+
this.decMinute();
|
|
159
|
+
}
|
|
160
|
+
return this.s;
|
|
161
|
+
}
|
|
162
|
+
incMinute() {
|
|
163
|
+
if (++this.m > 59) {
|
|
164
|
+
this.m = 0;
|
|
165
|
+
this.incHour();
|
|
166
|
+
}
|
|
167
|
+
return this.m;
|
|
168
|
+
}
|
|
169
|
+
decMinute() {
|
|
170
|
+
if (--this.m < 0) {
|
|
171
|
+
this.m = 59;
|
|
172
|
+
this.decHour();
|
|
173
|
+
}
|
|
174
|
+
return this.m;
|
|
175
|
+
}
|
|
176
|
+
incHour() {
|
|
177
|
+
if (++this.h > 23) {
|
|
178
|
+
this.h = 0;
|
|
179
|
+
this.incDay();
|
|
180
|
+
}
|
|
181
|
+
return this.h;
|
|
182
|
+
}
|
|
183
|
+
decHour() {
|
|
184
|
+
if (--this.h < 0) {
|
|
185
|
+
this.h = 23;
|
|
186
|
+
this.decDay();
|
|
187
|
+
}
|
|
188
|
+
return this.h;
|
|
189
|
+
}
|
|
190
|
+
incDay() {
|
|
191
|
+
if (++this.d > this.daysInMonth()) {
|
|
192
|
+
this.d = 1;
|
|
193
|
+
this.incMonth();
|
|
194
|
+
}
|
|
195
|
+
return this.d;
|
|
196
|
+
}
|
|
197
|
+
decDay() {
|
|
198
|
+
if (--this.d < 1) {
|
|
199
|
+
this.decMonth();
|
|
200
|
+
this.d = this.daysInMonth();
|
|
201
|
+
}
|
|
202
|
+
return this.d;
|
|
203
|
+
}
|
|
204
|
+
incWeek() {
|
|
205
|
+
this.d += 7;
|
|
206
|
+
const max = this.daysInMonth();
|
|
207
|
+
if (this.d > max) {
|
|
208
|
+
this.d -= max;
|
|
209
|
+
this.incMonth();
|
|
210
|
+
}
|
|
211
|
+
return this.weekInYear();
|
|
212
|
+
}
|
|
213
|
+
decWeek() {
|
|
214
|
+
this.d -= 7;
|
|
215
|
+
if (this.d < 1) {
|
|
216
|
+
this.decMonth();
|
|
217
|
+
this.d += this.daysInMonth();
|
|
218
|
+
}
|
|
219
|
+
return this.weekInYear();
|
|
220
|
+
}
|
|
221
|
+
incMonth() {
|
|
222
|
+
if (++this.M > 11) {
|
|
223
|
+
this.M = 0;
|
|
224
|
+
++this.y;
|
|
225
|
+
}
|
|
226
|
+
return this.M;
|
|
227
|
+
}
|
|
228
|
+
decMonth() {
|
|
229
|
+
if (--this.M < 0) {
|
|
230
|
+
this.M = 11;
|
|
231
|
+
--this.y;
|
|
232
|
+
}
|
|
233
|
+
return this.M;
|
|
234
|
+
}
|
|
235
|
+
incQuarter() {
|
|
236
|
+
this.M += 3;
|
|
237
|
+
if (this.M > 11) {
|
|
238
|
+
this.M %= 12;
|
|
239
|
+
this.y++;
|
|
240
|
+
}
|
|
241
|
+
return this.q;
|
|
242
|
+
}
|
|
243
|
+
decQuarter() {
|
|
244
|
+
this.M -= 3;
|
|
245
|
+
if (this.M < 0) {
|
|
246
|
+
this.M += 12;
|
|
247
|
+
this.y--;
|
|
248
|
+
}
|
|
249
|
+
return this.q;
|
|
250
|
+
}
|
|
251
|
+
incYear() {
|
|
252
|
+
return ++this.y;
|
|
253
|
+
}
|
|
254
|
+
decYear() {
|
|
255
|
+
return --this.y;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Returns a new `DateTime` instance relative to this date, but with given
|
|
259
|
+
* period added/subtracted.
|
|
260
|
+
*
|
|
261
|
+
* @param x -
|
|
262
|
+
* @param prec -
|
|
263
|
+
*/
|
|
264
|
+
add(x, prec) {
|
|
265
|
+
if (prec === "w")
|
|
266
|
+
return this.add(x * 7, "d");
|
|
267
|
+
if (prec === "q")
|
|
268
|
+
return this.add(x * 3, "M");
|
|
269
|
+
const res = this.copy();
|
|
270
|
+
const precID = __precisionToID(prec);
|
|
271
|
+
if (precID >= 2) {
|
|
272
|
+
res.set(
|
|
273
|
+
res.getTime() + x * [DAY, HOUR, MINUTE, SECOND, 1][precID - 2]
|
|
274
|
+
);
|
|
275
|
+
} else if (prec === "M") {
|
|
276
|
+
const y = x / 12 | 0;
|
|
277
|
+
res.y += y;
|
|
278
|
+
x -= y * 12;
|
|
279
|
+
const m = res.M + x;
|
|
280
|
+
m > 11 && res.y++;
|
|
281
|
+
m < 0 && res.y--;
|
|
282
|
+
res.M = m % 12;
|
|
283
|
+
if (res.M < 0)
|
|
284
|
+
res.M += 12;
|
|
285
|
+
res.d = Math.min(res.d, res.daysInMonth());
|
|
286
|
+
} else if (prec === "y") {
|
|
287
|
+
res.y += x;
|
|
288
|
+
}
|
|
289
|
+
return res;
|
|
290
|
+
}
|
|
291
|
+
toDate() {
|
|
292
|
+
return new Date(this.toISOString());
|
|
293
|
+
}
|
|
294
|
+
toJSON() {
|
|
295
|
+
return this.toISOString();
|
|
296
|
+
}
|
|
297
|
+
toString() {
|
|
298
|
+
return this.toDate().toUTCString();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Returns formatted version using current {@link LOCALE.dateTime}
|
|
302
|
+
* formatter.
|
|
303
|
+
*
|
|
304
|
+
* @remarks
|
|
305
|
+
* The host environment's locale is NOT used. Only the currently active
|
|
306
|
+
* `LOCALE` is relevant.
|
|
307
|
+
*/
|
|
308
|
+
toLocaleString() {
|
|
309
|
+
return defFormat(LOCALE.dateTime)(this, true);
|
|
310
|
+
}
|
|
311
|
+
toISOString() {
|
|
312
|
+
return `${Z4(this.y)}-${Z2(this.M + 1)}-${Z2(this.d)}T${Z2(
|
|
313
|
+
this.h
|
|
314
|
+
)}:${Z2(this.m)}:${Z2(this.s)}.${Z3(this.t)}Z`;
|
|
315
|
+
}
|
|
316
|
+
valueOf() {
|
|
317
|
+
return this.getTime();
|
|
318
|
+
}
|
|
318
319
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
*
|
|
328
|
-
* @param x -
|
|
329
|
-
*/
|
|
330
|
-
export const maybeIsDate = (x) => x instanceof DateTime || x instanceof Date || isNumber(x) || isString(x);
|
|
320
|
+
const ensureDateTime = (x, prec = "t") => x instanceof DateTime ? x : new DateTime(x, prec);
|
|
321
|
+
const maybeIsDate = (x) => x instanceof DateTime || x instanceof Date || isNumber(x) || isString(x);
|
|
322
|
+
export {
|
|
323
|
+
DateTime,
|
|
324
|
+
dateTime,
|
|
325
|
+
ensureDateTime,
|
|
326
|
+
maybeIsDate
|
|
327
|
+
};
|