@naturalcycles/js-lib 14.98.3 → 14.99.2
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/dist/array/array.util.d.ts +10 -1
- package/dist/array/array.util.js +36 -2
- package/dist/datetime/localDate.d.ts +13 -10
- package/dist/datetime/localDate.js +47 -22
- package/dist/datetime/localTime.d.ts +24 -8
- package/dist/datetime/localTime.js +228 -78
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -0
- package/dist/vendor/is.d.ts +2 -0
- package/dist-esm/array/array.util.js +30 -1
- package/dist-esm/datetime/localDate.js +47 -22
- package/dist-esm/datetime/localTime.js +227 -77
- package/dist-esm/index.js +1 -0
- package/package.json +1 -1
- package/src/array/array.util.ts +30 -1
- package/src/datetime/localDate.ts +65 -31
- package/src/datetime/localTime.ts +260 -91
- package/src/index.ts +18 -2
|
@@ -3,9 +3,20 @@ import { _ms } from '../time/time.util'
|
|
|
3
3
|
import { IsoDateString, IsoDateTimeString, UnixTimestampNumber } from '../types'
|
|
4
4
|
import { Inclusiveness, LocalDate } from './localDate'
|
|
5
5
|
|
|
6
|
-
export type LocalTimeUnit = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'
|
|
6
|
+
export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second'
|
|
7
|
+
|
|
8
|
+
export enum ISODayOfWeek {
|
|
9
|
+
MONDAY = 1,
|
|
10
|
+
TUESDAY = 2,
|
|
11
|
+
WEDNESDAY = 3,
|
|
12
|
+
THURSDAY = 4,
|
|
13
|
+
FRIDAY = 5,
|
|
14
|
+
SATURDAY = 6,
|
|
15
|
+
SUNDAY = 7,
|
|
16
|
+
}
|
|
7
17
|
|
|
8
18
|
export type LocalTimeConfig = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber
|
|
19
|
+
export type LocalTimeFormatter = (ld: LocalTime) => string
|
|
9
20
|
|
|
10
21
|
export interface LocalTimeComponents {
|
|
11
22
|
year: number
|
|
@@ -16,13 +27,20 @@ export interface LocalTimeComponents {
|
|
|
16
27
|
second: number
|
|
17
28
|
}
|
|
18
29
|
|
|
30
|
+
const weekStartsOn = 1 // mon, as per ISO
|
|
31
|
+
const MILLISECONDS_IN_WEEK = 604800000
|
|
32
|
+
const SECONDS_IN_DAY = 86400
|
|
33
|
+
// const MILLISECONDS_IN_DAY = 86400000
|
|
34
|
+
// const MILLISECONDS_IN_MINUTE = 60000
|
|
35
|
+
const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7])
|
|
36
|
+
|
|
19
37
|
/* eslint-disable no-dupe-class-members */
|
|
20
38
|
|
|
21
39
|
/**
|
|
22
40
|
* @experimental
|
|
23
41
|
*/
|
|
24
42
|
export class LocalTime {
|
|
25
|
-
private constructor(private $date: Date
|
|
43
|
+
private constructor(private $date: Date) {}
|
|
26
44
|
|
|
27
45
|
/**
|
|
28
46
|
* Parses input String into LocalDate.
|
|
@@ -38,16 +56,6 @@ export class LocalTime {
|
|
|
38
56
|
return t
|
|
39
57
|
}
|
|
40
58
|
|
|
41
|
-
utc(): this {
|
|
42
|
-
this.utcMode = true
|
|
43
|
-
return this
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
local(): this {
|
|
47
|
-
this.utcMode = false
|
|
48
|
-
return this
|
|
49
|
-
}
|
|
50
|
-
|
|
51
59
|
/**
|
|
52
60
|
* Returns null if invalid
|
|
53
61
|
*/
|
|
@@ -75,7 +83,7 @@ export class LocalTime {
|
|
|
75
83
|
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
76
84
|
// }
|
|
77
85
|
|
|
78
|
-
return new LocalTime(date
|
|
86
|
+
return new LocalTime(date)
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
static parseToDate(d: LocalTimeConfig): Date {
|
|
@@ -109,53 +117,56 @@ export class LocalTime {
|
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
static now(): LocalTime {
|
|
112
|
-
return new LocalTime(new Date()
|
|
120
|
+
return new LocalTime(new Date())
|
|
113
121
|
}
|
|
114
122
|
|
|
115
123
|
static fromComponents(
|
|
116
124
|
c: { year: number; month: number } & Partial<LocalTimeComponents>,
|
|
117
125
|
): LocalTime {
|
|
118
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second)
|
|
126
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second))
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
get(unit: LocalTimeUnit): number {
|
|
122
130
|
if (unit === 'year') {
|
|
123
|
-
return this
|
|
131
|
+
return this.$date.getFullYear()
|
|
124
132
|
}
|
|
125
133
|
if (unit === 'month') {
|
|
126
|
-
return
|
|
134
|
+
return this.$date.getMonth() + 1
|
|
127
135
|
}
|
|
128
136
|
if (unit === 'day') {
|
|
129
|
-
return this
|
|
137
|
+
return this.$date.getDate()
|
|
130
138
|
}
|
|
131
139
|
if (unit === 'hour') {
|
|
132
|
-
return this
|
|
140
|
+
return this.$date.getHours()
|
|
133
141
|
}
|
|
134
142
|
if (unit === 'minute') {
|
|
135
|
-
return this
|
|
143
|
+
return this.$date.getMinutes()
|
|
144
|
+
}
|
|
145
|
+
if (unit === 'week') {
|
|
146
|
+
return getWeek(this.$date)
|
|
136
147
|
}
|
|
137
148
|
// second
|
|
138
|
-
return this
|
|
149
|
+
return this.$date.getSeconds()
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
set(unit: LocalTimeUnit, v: number, mutate = false): LocalTime {
|
|
142
153
|
const t = mutate ? this : this.clone()
|
|
143
154
|
|
|
144
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
145
155
|
if (unit === 'year') {
|
|
146
|
-
|
|
156
|
+
t.$date.setFullYear(v)
|
|
147
157
|
} else if (unit === 'month') {
|
|
148
|
-
|
|
158
|
+
t.$date.setMonth(v - 1)
|
|
149
159
|
} else if (unit === 'day') {
|
|
150
|
-
|
|
160
|
+
t.$date.setDate(v)
|
|
151
161
|
} else if (unit === 'hour') {
|
|
152
|
-
|
|
162
|
+
t.$date.setHours(v)
|
|
153
163
|
} else if (unit === 'minute') {
|
|
154
|
-
|
|
164
|
+
t.$date.setMinutes(v)
|
|
155
165
|
} else if (unit === 'second') {
|
|
156
|
-
|
|
166
|
+
t.$date.setSeconds(v)
|
|
167
|
+
} else if (unit === 'week') {
|
|
168
|
+
setWeek(t.$date, v, true)
|
|
157
169
|
}
|
|
158
|
-
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
159
170
|
|
|
160
171
|
return t
|
|
161
172
|
}
|
|
@@ -170,11 +181,33 @@ export class LocalTime {
|
|
|
170
181
|
month(v?: number): number | LocalTime {
|
|
171
182
|
return v === undefined ? this.get('month') : this.set('month', v)
|
|
172
183
|
}
|
|
184
|
+
week(): number
|
|
185
|
+
week(v: number): LocalTime
|
|
186
|
+
week(v?: number): number | LocalTime {
|
|
187
|
+
return v === undefined ? getWeek(this.$date) : this.set('week', v)
|
|
188
|
+
}
|
|
173
189
|
day(): number
|
|
174
190
|
day(v: number): LocalTime
|
|
175
191
|
day(v?: number): number | LocalTime {
|
|
176
192
|
return v === undefined ? this.get('day') : this.set('day', v)
|
|
177
193
|
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Based on ISO: 1-7 is Mon-Sun.
|
|
197
|
+
*/
|
|
198
|
+
dayOfWeek(): ISODayOfWeek
|
|
199
|
+
dayOfWeek(v: ISODayOfWeek): LocalTime
|
|
200
|
+
dayOfWeek(v?: ISODayOfWeek): ISODayOfWeek | LocalTime {
|
|
201
|
+
const dow = (this.$date.getDay() || 7) as ISODayOfWeek
|
|
202
|
+
|
|
203
|
+
if (v === undefined) {
|
|
204
|
+
return dow
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!VALID_DAYS_OF_WEEK.has(v)) throw new Error(`Invalid dayOfWeek: ${v}`)
|
|
208
|
+
|
|
209
|
+
return this.add(v - dow, 'day')
|
|
210
|
+
}
|
|
178
211
|
hour(): number
|
|
179
212
|
hour(v: number): LocalTime
|
|
180
213
|
hour(v?: number): number | LocalTime {
|
|
@@ -194,31 +227,33 @@ export class LocalTime {
|
|
|
194
227
|
setComponents(c: Partial<LocalTimeComponents>, mutate = false): LocalTime {
|
|
195
228
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
196
229
|
|
|
197
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
198
230
|
if (c.year) {
|
|
199
|
-
|
|
231
|
+
d.setFullYear(c.year)
|
|
200
232
|
}
|
|
201
233
|
if (c.month) {
|
|
202
|
-
|
|
234
|
+
d.setMonth(c.month - 1)
|
|
203
235
|
}
|
|
204
236
|
if (c.day) {
|
|
205
|
-
|
|
237
|
+
d.setDate(c.day)
|
|
206
238
|
}
|
|
207
239
|
if (c.hour !== undefined) {
|
|
208
|
-
|
|
240
|
+
d.setHours(c.hour)
|
|
209
241
|
}
|
|
210
242
|
if (c.minute !== undefined) {
|
|
211
|
-
|
|
243
|
+
d.setMinutes(c.minute)
|
|
212
244
|
}
|
|
213
245
|
if (c.second !== undefined) {
|
|
214
|
-
|
|
246
|
+
d.setSeconds(c.second)
|
|
215
247
|
}
|
|
216
|
-
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
217
248
|
|
|
218
|
-
return mutate ? this : new LocalTime(d
|
|
249
|
+
return mutate ? this : new LocalTime(d)
|
|
219
250
|
}
|
|
220
251
|
|
|
221
252
|
add(num: number, unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
253
|
+
if (unit === 'week') {
|
|
254
|
+
num *= 7
|
|
255
|
+
unit = 'day'
|
|
256
|
+
}
|
|
222
257
|
return this.set(unit, this.get(unit) + num, mutate)
|
|
223
258
|
}
|
|
224
259
|
|
|
@@ -233,24 +268,45 @@ export class LocalTime {
|
|
|
233
268
|
diff(other: LocalTimeConfig, unit: LocalTimeUnit): number {
|
|
234
269
|
const date2 = LocalTime.parseToDate(other)
|
|
235
270
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (unit === 'month') {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
271
|
+
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000
|
|
272
|
+
if (!secDiff) return 0
|
|
273
|
+
|
|
274
|
+
if (unit === 'year' || unit === 'month') {
|
|
275
|
+
const sign = secDiff > 0 ? 1 : -1
|
|
276
|
+
|
|
277
|
+
// Put items in descending order: "big minus small"
|
|
278
|
+
const [big, small] = sign === 1 ? [this.$date, date2] : [date2, this.$date]
|
|
279
|
+
|
|
280
|
+
if (unit === 'year') {
|
|
281
|
+
let years = big.getFullYear() - small.getFullYear()
|
|
282
|
+
const big2 = new Date(big)
|
|
283
|
+
const small2 = new Date(small)
|
|
284
|
+
big2.setFullYear(1584)
|
|
285
|
+
small2.setFullYear(1584)
|
|
286
|
+
if (big2 < small2) years--
|
|
287
|
+
return years * sign || 0
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (unit === 'month') {
|
|
291
|
+
let months =
|
|
292
|
+
(big.getFullYear() - small.getFullYear()) * 12 + big.getMonth() - small.getMonth()
|
|
293
|
+
const big2 = new Date(big)
|
|
294
|
+
const small2 = new Date(small)
|
|
295
|
+
big2.setFullYear(1584, 0)
|
|
296
|
+
small2.setFullYear(1584, 0)
|
|
297
|
+
if (big2 < small2) months--
|
|
298
|
+
return months * sign || 0
|
|
299
|
+
}
|
|
245
300
|
}
|
|
246
301
|
|
|
247
|
-
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000
|
|
248
302
|
let r
|
|
249
303
|
|
|
250
304
|
if (unit === 'day') {
|
|
251
|
-
r = secDiff /
|
|
305
|
+
r = secDiff / SECONDS_IN_DAY
|
|
306
|
+
} else if (unit === 'week') {
|
|
307
|
+
r = secDiff / (7 * 24 * 60 * 60)
|
|
252
308
|
} else if (unit === 'hour') {
|
|
253
|
-
r = secDiff /
|
|
309
|
+
r = secDiff / 3600
|
|
254
310
|
} else if (unit === 'minute') {
|
|
255
311
|
r = secDiff / 60
|
|
256
312
|
} else {
|
|
@@ -258,34 +314,66 @@ export class LocalTime {
|
|
|
258
314
|
r = secDiff
|
|
259
315
|
}
|
|
260
316
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return r
|
|
317
|
+
// `|| 0` is to avoid returning -0
|
|
318
|
+
return Math.trunc(r) || 0
|
|
264
319
|
}
|
|
265
320
|
|
|
266
321
|
startOf(unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
267
322
|
if (unit === 'second') return this
|
|
323
|
+
const d = mutate ? this.$date : new Date(this.$date)
|
|
324
|
+
d.setSeconds(0, 0)
|
|
325
|
+
|
|
326
|
+
if (unit !== 'minute') {
|
|
327
|
+
d.setMinutes(0)
|
|
328
|
+
if (unit !== 'hour') {
|
|
329
|
+
d.setHours(0)
|
|
330
|
+
if (unit !== 'day') {
|
|
331
|
+
// year, month or week
|
|
332
|
+
|
|
333
|
+
if (unit === 'year') {
|
|
334
|
+
d.setMonth(0)
|
|
335
|
+
d.setDate(1)
|
|
336
|
+
} else if (unit === 'month') {
|
|
337
|
+
d.setDate(1)
|
|
338
|
+
} else {
|
|
339
|
+
// week
|
|
340
|
+
startOfWeek(d, true)
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return mutate ? this : new LocalTime(d)
|
|
347
|
+
}
|
|
268
348
|
|
|
349
|
+
endOf(unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
350
|
+
if (unit === 'second') return this
|
|
269
351
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
270
|
-
d.
|
|
271
|
-
d.setSeconds(0)
|
|
352
|
+
d.setSeconds(59, 0)
|
|
272
353
|
|
|
273
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
274
354
|
if (unit !== 'minute') {
|
|
275
|
-
|
|
355
|
+
d.setMinutes(59)
|
|
276
356
|
if (unit !== 'hour') {
|
|
277
|
-
|
|
357
|
+
d.setHours(23)
|
|
278
358
|
if (unit !== 'day') {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
359
|
+
// year, month or week
|
|
360
|
+
|
|
361
|
+
if (unit === 'year') {
|
|
362
|
+
d.setMonth(11)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (unit === 'week') {
|
|
366
|
+
endOfWeek(d, true)
|
|
367
|
+
} else {
|
|
368
|
+
// year or month
|
|
369
|
+
const lastDay = LocalDate.getMonthLength(d.getFullYear(), d.getMonth() + 1)
|
|
370
|
+
d.setDate(lastDay)
|
|
282
371
|
}
|
|
283
372
|
}
|
|
284
373
|
}
|
|
285
374
|
}
|
|
286
|
-
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
287
375
|
|
|
288
|
-
return mutate ? this : new LocalTime(d
|
|
376
|
+
return mutate ? this : new LocalTime(d)
|
|
289
377
|
}
|
|
290
378
|
|
|
291
379
|
static sort(items: LocalTime[], mutate = false, descending = false): LocalTime[] {
|
|
@@ -298,24 +386,28 @@ export class LocalTime {
|
|
|
298
386
|
})
|
|
299
387
|
}
|
|
300
388
|
|
|
301
|
-
static earliestOrUndefined(items:
|
|
389
|
+
static earliestOrUndefined(items: LocalTimeConfig[]): LocalTime | undefined {
|
|
302
390
|
return items.length ? LocalTime.earliest(items) : undefined
|
|
303
391
|
}
|
|
304
392
|
|
|
305
|
-
static earliest(items:
|
|
393
|
+
static earliest(items: LocalTimeConfig[]): LocalTime {
|
|
306
394
|
_assert(items.length, 'LocalTime.earliest called on empty array')
|
|
307
395
|
|
|
308
|
-
return items
|
|
396
|
+
return items
|
|
397
|
+
.map(i => LocalTime.of(i))
|
|
398
|
+
.reduce((min, item) => (min.isSameOrBefore(item) ? min : item))
|
|
309
399
|
}
|
|
310
400
|
|
|
311
|
-
static latestOrUndefined(items:
|
|
401
|
+
static latestOrUndefined(items: LocalTimeConfig[]): LocalTime | undefined {
|
|
312
402
|
return items.length ? LocalTime.latest(items) : undefined
|
|
313
403
|
}
|
|
314
404
|
|
|
315
|
-
static latest(items:
|
|
405
|
+
static latest(items: LocalTimeConfig[]): LocalTime {
|
|
316
406
|
_assert(items.length, 'LocalTime.latest called on empty array')
|
|
317
407
|
|
|
318
|
-
return items
|
|
408
|
+
return items
|
|
409
|
+
.map(i => LocalTime.of(i))
|
|
410
|
+
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item))
|
|
319
411
|
}
|
|
320
412
|
|
|
321
413
|
isSame(d: LocalTimeConfig): boolean {
|
|
@@ -360,20 +452,7 @@ export class LocalTime {
|
|
|
360
452
|
return t1 < t2 ? -1 : 1
|
|
361
453
|
}
|
|
362
454
|
|
|
363
|
-
// todo: endOf
|
|
364
|
-
|
|
365
455
|
components(): LocalTimeComponents {
|
|
366
|
-
if (this.utcMode) {
|
|
367
|
-
return {
|
|
368
|
-
year: this.$date.getUTCFullYear(),
|
|
369
|
-
month: this.$date.getUTCMonth() + 1,
|
|
370
|
-
day: this.$date.getUTCDate(),
|
|
371
|
-
hour: this.$date.getUTCHours(),
|
|
372
|
-
minute: this.$date.getUTCMinutes(),
|
|
373
|
-
second: this.$date.getSeconds(),
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
456
|
return {
|
|
378
457
|
year: this.$date.getFullYear(),
|
|
379
458
|
month: this.$date.getMonth() + 1,
|
|
@@ -401,7 +480,7 @@ export class LocalTime {
|
|
|
401
480
|
}
|
|
402
481
|
|
|
403
482
|
clone(): LocalTime {
|
|
404
|
-
return new LocalTime(new Date(this.$date)
|
|
483
|
+
return new LocalTime(new Date(this.$date))
|
|
405
484
|
}
|
|
406
485
|
|
|
407
486
|
unix(): UnixTimestampNumber {
|
|
@@ -417,14 +496,6 @@ export class LocalTime {
|
|
|
417
496
|
}
|
|
418
497
|
|
|
419
498
|
toLocalDate(): LocalDate {
|
|
420
|
-
if (this.utcMode) {
|
|
421
|
-
return LocalDate.create(
|
|
422
|
-
this.$date.getUTCFullYear(),
|
|
423
|
-
this.$date.getUTCMonth() + 1,
|
|
424
|
-
this.$date.getUTCDate(),
|
|
425
|
-
)
|
|
426
|
-
}
|
|
427
|
-
|
|
428
499
|
return LocalDate.create(
|
|
429
500
|
this.$date.getFullYear(),
|
|
430
501
|
this.$date.getMonth() + 1,
|
|
@@ -520,6 +591,10 @@ export class LocalTime {
|
|
|
520
591
|
toJSON(): UnixTimestampNumber {
|
|
521
592
|
return this.unix()
|
|
522
593
|
}
|
|
594
|
+
|
|
595
|
+
format(fmt: LocalTimeFormatter): string {
|
|
596
|
+
return fmt(this)
|
|
597
|
+
}
|
|
523
598
|
}
|
|
524
599
|
|
|
525
600
|
/**
|
|
@@ -528,3 +603,97 @@ export class LocalTime {
|
|
|
528
603
|
export function localTime(d?: LocalTimeConfig): LocalTime {
|
|
529
604
|
return d ? LocalTime.of(d) : LocalTime.now()
|
|
530
605
|
}
|
|
606
|
+
|
|
607
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/getISOWeek/index.ts
|
|
608
|
+
function getWeek(date: Date): number {
|
|
609
|
+
const diff = startOfWeek(date).getTime() - startOfWeekYear(date).getTime()
|
|
610
|
+
return Math.round(diff / MILLISECONDS_IN_WEEK) + 1
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
function setWeek(date: Date, week: number, mutate = false): Date {
|
|
614
|
+
const d = mutate ? date : new Date(date)
|
|
615
|
+
const diff = getWeek(d) - week
|
|
616
|
+
d.setDate(d.getDate() - diff * 7)
|
|
617
|
+
return d
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/startOfISOWeekYear/index.ts
|
|
621
|
+
function startOfWeekYear(date: Date): Date {
|
|
622
|
+
const year = getWeekYear(date)
|
|
623
|
+
const fourthOfJanuary = new Date(0)
|
|
624
|
+
fourthOfJanuary.setFullYear(year, 0, 4)
|
|
625
|
+
fourthOfJanuary.setHours(0, 0, 0, 0)
|
|
626
|
+
return startOfWeek(fourthOfJanuary, true)
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/getISOWeekYear/index.ts
|
|
630
|
+
function getWeekYear(date: Date): number {
|
|
631
|
+
const year = date.getFullYear()
|
|
632
|
+
|
|
633
|
+
const fourthOfJanuaryOfNextYear = new Date(0)
|
|
634
|
+
fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4)
|
|
635
|
+
fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0)
|
|
636
|
+
const startOfNextYear = startOfWeek(fourthOfJanuaryOfNextYear, true)
|
|
637
|
+
|
|
638
|
+
const fourthOfJanuaryOfThisYear = new Date(0)
|
|
639
|
+
fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4)
|
|
640
|
+
fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0)
|
|
641
|
+
const startOfThisYear = startOfWeek(fourthOfJanuaryOfThisYear, true)
|
|
642
|
+
|
|
643
|
+
if (date.getTime() >= startOfNextYear.getTime()) {
|
|
644
|
+
return year + 1
|
|
645
|
+
} else if (date.getTime() >= startOfThisYear.getTime()) {
|
|
646
|
+
return year
|
|
647
|
+
} else {
|
|
648
|
+
return year - 1
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// function setWeekYear(
|
|
653
|
+
// date: Date,
|
|
654
|
+
// year: number,
|
|
655
|
+
// ): Date {
|
|
656
|
+
// const diff = differenceInCalendarDays(date, startOfWeekYear(date))
|
|
657
|
+
// const fourthOfJanuary = new Date(0)
|
|
658
|
+
// fourthOfJanuary.setFullYear(year, 0, 4)
|
|
659
|
+
// fourthOfJanuary.setHours(0, 0, 0, 0)
|
|
660
|
+
// date = startOfWeekYear(fourthOfJanuary)
|
|
661
|
+
// date.setDate(date.getDate() + diff)
|
|
662
|
+
// return date
|
|
663
|
+
// }
|
|
664
|
+
|
|
665
|
+
// function differenceInCalendarDays(
|
|
666
|
+
// dateLeft: Date,
|
|
667
|
+
// dateRight: Date,
|
|
668
|
+
// ): number {
|
|
669
|
+
// return Math.round((startOfDay(dateLeft).getTime() - startOfDay(dateRight).getTime()) / MILLISECONDS_IN_DAY)
|
|
670
|
+
// }
|
|
671
|
+
|
|
672
|
+
// function startOfDay(date: Date, mutate = false): Date {
|
|
673
|
+
// const d = mutate ? date : new Date(date)
|
|
674
|
+
// d.setHours(0, 0, 0, 0)
|
|
675
|
+
// return d
|
|
676
|
+
// }
|
|
677
|
+
|
|
678
|
+
// based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
|
|
679
|
+
function startOfWeek(date: Date, mutate = false): Date {
|
|
680
|
+
const d = mutate ? date : new Date(date)
|
|
681
|
+
|
|
682
|
+
const day = d.getDay()
|
|
683
|
+
const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn
|
|
684
|
+
|
|
685
|
+
d.setDate(d.getDate() - diff)
|
|
686
|
+
d.setHours(0, 0, 0, 0)
|
|
687
|
+
return d
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/endOfWeek/index.ts
|
|
691
|
+
function endOfWeek(date: Date, mutate = false): Date {
|
|
692
|
+
const d = mutate ? date : new Date(date)
|
|
693
|
+
|
|
694
|
+
const day = d.getDay()
|
|
695
|
+
const diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn)
|
|
696
|
+
|
|
697
|
+
d.setDate(d.getDate() + diff)
|
|
698
|
+
return d
|
|
699
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -162,8 +162,20 @@ export * from './datetime/localDate'
|
|
|
162
162
|
export * from './datetime/localTime'
|
|
163
163
|
export * from './datetime/dateInterval'
|
|
164
164
|
export * from './datetime/timeInterval'
|
|
165
|
-
import {
|
|
166
|
-
|
|
165
|
+
import {
|
|
166
|
+
LocalDateConfig,
|
|
167
|
+
LocalDateFormatter,
|
|
168
|
+
LocalDateUnit,
|
|
169
|
+
LocalDateUnitStrict,
|
|
170
|
+
Inclusiveness,
|
|
171
|
+
} from './datetime/localDate'
|
|
172
|
+
import {
|
|
173
|
+
LocalTimeConfig,
|
|
174
|
+
LocalTimeFormatter,
|
|
175
|
+
LocalTimeUnit,
|
|
176
|
+
LocalTimeComponents,
|
|
177
|
+
ISODayOfWeek,
|
|
178
|
+
} from './datetime/localTime'
|
|
167
179
|
import { DateIntervalConfig, DateIntervalString } from './datetime/dateInterval'
|
|
168
180
|
import { TimeIntervalConfig, TimeIntervalString } from './datetime/timeInterval'
|
|
169
181
|
|
|
@@ -173,10 +185,14 @@ export type {
|
|
|
173
185
|
TimeIntervalConfig,
|
|
174
186
|
TimeIntervalString,
|
|
175
187
|
LocalDateConfig,
|
|
188
|
+
LocalDateFormatter,
|
|
176
189
|
LocalDateUnit,
|
|
190
|
+
LocalDateUnitStrict,
|
|
177
191
|
Inclusiveness,
|
|
178
192
|
LocalTimeConfig,
|
|
193
|
+
LocalTimeFormatter,
|
|
179
194
|
LocalTimeUnit,
|
|
195
|
+
ISODayOfWeek,
|
|
180
196
|
LocalTimeComponents,
|
|
181
197
|
AbortableMapper,
|
|
182
198
|
AbortablePredicate,
|