qrono 1.2.1 → 1.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.
package/src/qrono.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @ts-self-types="../types/qrono.d.ts" */
1
+ /* @ts-self-types="../types/qrono.d.ts" */
2
2
  import {
3
3
  has,
4
4
  given,
@@ -33,16 +33,6 @@ const defaultContext = {
33
33
  disambiguation: 'compatible',
34
34
  }
35
35
 
36
- for (const key of fields(defaultContext)) {
37
- Qrono[key] = function (arg) {
38
- if (given(arg)) {
39
- defaultContext[key] = arg
40
- return this
41
- }
42
- return defaultContext[key]
43
- }
44
- }
45
-
46
36
  Qrono.context = function (context) {
47
37
  if (given(context)) {
48
38
  for (const key of fields(defaultContext)) {
@@ -56,16 +46,6 @@ Qrono.context = function (context) {
56
46
  return { ...defaultContext }
57
47
  }
58
48
 
59
- Qrono.asUtc = function () {
60
- defaultContext.localtime = false
61
- return this
62
- }
63
-
64
- Qrono.asLocaltime = function () {
65
- defaultContext.localtime = true
66
- return this
67
- }
68
-
69
49
  const monday = 1
70
50
  const tuesday = 2
71
51
  const wednesday = 3
@@ -111,9 +91,8 @@ function Qrono(...args) {
111
91
  self.context(defaultContext)
112
92
  if (args[0] instanceof Qrono) {
113
93
  const source = args.shift()
114
- for (const key of fields(self)) {
115
- self[key] = source[key]()
116
- }
94
+ self.nativeDate = source.nativeDate()
95
+ self.context(source.context())
117
96
  }
118
97
  if (isObject(args[0]) && !hasDatetimeField(args[0])) {
119
98
  self.context(args.shift())
@@ -167,15 +146,12 @@ function valid() {
167
146
  return isValidDate(this.nativeDate)
168
147
  }
169
148
 
170
- function context(context) {
171
- if (!context) {
172
- return
173
- }
174
- for (const key of fields(defaultContext)) {
175
- if (has(context, key)) {
176
- this[key] = context[key]
177
- }
149
+ function context(arg) {
150
+ if (!arg) {
151
+ return { localtime: this.localtime, disambiguation: this.disambiguation }
178
152
  }
153
+ if ('localtime' in arg) this.localtime = arg.localtime
154
+ if ('disambiguation' in arg) this.disambiguation = arg.disambiguation
179
155
  return this
180
156
  }
181
157
 
@@ -205,7 +181,7 @@ function set(values) {
205
181
  }
206
182
  const dateOnly = !has(values, 'hour', 'minute', 'second', 'millisecond')
207
183
  const disambig = dateOnly ? 'later' : this.disambiguation
208
- const baseDate = this.nativeDate ?? new Date(0, 0)
184
+ const baseDate = this.nativeDate ?? new Date(0, 0) // 1900-01-01T00:00:00.000Z
209
185
  const newDate = new Date(initialSafeDate.getTime())
210
186
  const requested = {
211
187
  year: args.year ?? baseDate.getFullYear(),
@@ -322,7 +298,7 @@ function parse(str) {
322
298
  // -----------------------------------------------------------------------------
323
299
  // Public methods
324
300
  // -----------------------------------------------------------------------------
325
- const p = (v, n) => String(v).padStart(n, '0')
301
+ const pad0 = (v, n) => String(v).padStart(n, '0')
326
302
 
327
303
  // Basic
328
304
  Qrono.prototype.toString = function () {
@@ -331,16 +307,16 @@ Qrono.prototype.toString = function () {
331
307
  const offset = -t.getTimezoneOffset()
332
308
  const offsetAbs = Math.abs(offset)
333
309
  return (
334
- `${p(t.getFullYear(), 4)}-` +
335
- `${p(t.getMonth() + 1, 2)}-` +
336
- `${p(t.getDate(), 2)}T` +
337
- `${p(t.getHours(), 2)}:` +
338
- `${p(t.getMinutes(), 2)}:` +
339
- `${p(t.getSeconds(), 2)}.` +
340
- `${p(t.getMilliseconds(), 3)}` +
310
+ `${pad0(t.getFullYear(), 4)}-` +
311
+ `${pad0(t.getMonth() + 1, 2)}-` +
312
+ `${pad0(t.getDate(), 2)}T` +
313
+ `${pad0(t.getHours(), 2)}:` +
314
+ `${pad0(t.getMinutes(), 2)}:` +
315
+ `${pad0(t.getSeconds(), 2)}.` +
316
+ `${pad0(t.getMilliseconds(), 3)}` +
341
317
  `${offset >= 0 ? '+' : '-'}` +
342
- `${p(Math.trunc(offsetAbs / minutesPerHour), 2)}:` +
343
- `${p(offsetAbs % minutesPerHour, 2)}`
318
+ `${pad0(Math.trunc(offsetAbs / minutesPerHour), 2)}:` +
319
+ `${pad0(offsetAbs % minutesPerHour, 2)}`
344
320
  )
345
321
  }
346
322
  return this[internal].nativeDate.toISOString()
@@ -373,25 +349,11 @@ Qrono.prototype.offset = function () {
373
349
  : 0
374
350
  }
375
351
 
376
- Qrono.prototype.localtime = function (arg) {
377
- return given(arg) ? this.clone({ localtime: arg }) : this[internal].localtime
378
- }
379
-
380
- Qrono.prototype.disambiguation = function (arg) {
381
- return given(arg)
382
- ? this.clone({ disambiguation: arg })
383
- : this[internal].disambiguation
384
- }
385
-
386
352
  Qrono.prototype.valid = function () {
387
353
  return this[internal].valid()
388
354
  }
389
355
 
390
356
  // Transform
391
- Qrono.prototype.numeric = function () {
392
- return this[internal].nativeDate.getTime()
393
- }
394
-
395
357
  Qrono.prototype.toObject = function () {
396
358
  return {
397
359
  year: this.year(),
@@ -420,17 +382,8 @@ Qrono.prototype.toDate = function (...args) {
420
382
  return new QronoDate(this.clone(...args))
421
383
  }
422
384
 
423
- // Context
424
- Qrono.prototype.asUtc = function () {
425
- return this.clone({ localtime: false })
426
- }
427
-
428
- Qrono.prototype.asLocaltime = function () {
429
- return this.clone({ localtime: true })
430
- }
431
-
432
385
  // Accessor
433
- for (const [field, native, offset] of [
386
+ for (const [field, native, base] of [
434
387
  ['year', 'FullYear', 0],
435
388
  ['month', 'Month', 1],
436
389
  ['day', 'Date', 0],
@@ -442,7 +395,7 @@ for (const [field, native, offset] of [
442
395
  Qrono.prototype[field] = function (value) {
443
396
  return given(value)
444
397
  ? this.clone({ [field]: value })
445
- : this[internal].getNative(native) + offset
398
+ : this[internal].getNative(native) + base
446
399
  }
447
400
  }
448
401
 
@@ -479,7 +432,7 @@ Qrono.prototype.isLeapYear = function () {
479
432
  return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
480
433
  }
481
434
 
482
- Qrono.prototype.hasDstInYear = function () {
435
+ Qrono.prototype.hasOffsetChangeInYear = function () {
483
436
  if (!this[internal].localtime) {
484
437
  return false
485
438
  }
@@ -490,18 +443,19 @@ Qrono.prototype.hasDstInYear = function () {
490
443
  }
491
444
 
492
445
  Qrono.prototype.isInDst = function () {
493
- if (!this[internal].localtime) {
494
- return false
446
+ if (!this[internal].localtime) return false
447
+ const offset = this.offset()
448
+ let past = false,
449
+ future = false
450
+ for (let i = 1; i <= 5; i += 2) {
451
+ if (this.month(-i).offset() < offset) past = true
452
+ if (this.month(i).offset() < offset) future = true
453
+ if (past && future) return true
495
454
  }
496
- const offsets = Array.from({ length: 12 }, (_, index) =>
497
- this.month(index + 1).offset()
498
- )
499
- const minOffset = Math.min(...offsets)
500
- const maxOffset = Math.max(...offsets)
501
- return minOffset !== maxOffset && this.offset() === maxOffset
455
+ return false
502
456
  }
503
457
 
504
- Qrono.prototype.isDstTransitionDay = function () {
458
+ Qrono.prototype.hasOffsetChangeInDay = function () {
505
459
  if (!this[internal].localtime) {
506
460
  return false
507
461
  }
@@ -558,28 +512,34 @@ Qrono.prototype.startOfDay = function () {
558
512
  const timestamp = this.clone(
559
513
  { disambiguation: 'later' },
560
514
  { hour: 0, minute: 0, second: 0, millisecond: 0 }
561
- ).numeric()
515
+ ).valueOf()
562
516
  return this.clone(timestamp)
563
517
  }
564
518
 
565
- Qrono.prototype.isSame = function (another) {
566
- return +this === +another
567
- }
568
- Qrono.prototype.isBefore = function (another) {
569
- return this < another
570
- }
571
- Qrono.prototype.isAfter = function (another) {
572
- return this > another
573
- }
574
- Qrono.prototype.isSameOrBefore = function (another) {
575
- return this <= another
576
- }
577
- Qrono.prototype.isSameOrAfter = function (another) {
578
- return this >= another
579
- }
580
- Qrono.prototype.isBetween = function (a, b) {
581
- return (a <= this && this <= b) || (b <= this && this <= a)
582
- }
519
+ function implementComparison(prototype) {
520
+ Object.assign(prototype, {
521
+ isSame(another) {
522
+ return +this === +another
523
+ },
524
+ isBefore(another) {
525
+ return this < another
526
+ },
527
+ isAfter(another) {
528
+ return this > another
529
+ },
530
+ isSameOrBefore(another) {
531
+ return this <= another
532
+ },
533
+ isSameOrAfter(another) {
534
+ return this >= another
535
+ },
536
+ isBetween(a, b) {
537
+ return (a <= this && this <= b) || (b <= this && this <= a)
538
+ },
539
+ })
540
+ }
541
+
542
+ implementComparison(Qrono.prototype)
583
543
 
584
544
  // Calculation
585
545
  Qrono.prototype.plus = function (...args) {
@@ -594,7 +554,7 @@ function plus(sign, ...args) {
594
554
  const arg0 = args[0]
595
555
  const arg1 = args[1]
596
556
  if (Number.isFinite(arg0) && !Number.isFinite(arg1)) {
597
- return this.clone(this.numeric() + arg0)
557
+ return this.clone(this.valueOf() + arg0)
598
558
  }
599
559
  let timeFields = null
600
560
  if (isObject(arg0)) {
@@ -710,10 +670,6 @@ QronoDate.prototype.toDatetime = function () {
710
670
  return qrono(this[internalDate].datetime.toArray())
711
671
  }
712
672
 
713
- QronoDate.prototype.numeric = function () {
714
- return this[internalDate].datetime.numeric() / millisecondsPerDay
715
- }
716
-
717
673
  QronoDate.prototype.toObject = function () {
718
674
  return {
719
675
  year: this.year(),
@@ -726,17 +682,12 @@ QronoDate.prototype.toArray = function () {
726
682
  return [this.year(), this.month(), this.day()]
727
683
  }
728
684
 
729
- QronoDate.prototype.startOfYear = function () {
730
- return new QronoDate(this[internalDate].datetime.startOfYear())
731
- }
732
-
733
- QronoDate.prototype.startOfMonth = function () {
734
- return new QronoDate(this[internalDate].datetime.startOfMonth())
685
+ for (const name of ['Year', 'Month']) {
686
+ QronoDate.prototype[`startOf${name}`] = function () {
687
+ return new QronoDate(this[internalDate].datetime[`startOf${name}`]())
688
+ }
735
689
  }
736
690
 
737
- QronoDate.prototype.startOfDay = function () {
738
- return this[internalDate].datetime.clone()
739
- }
740
691
  for (const field of ['year', 'month', 'day']) {
741
692
  QronoDate.prototype[field] = function (value) {
742
693
  if (given(value)) {
@@ -759,7 +710,11 @@ for (const method of [
759
710
  return this[internalDate].datetime[method]()
760
711
  }
761
712
  }
762
- for (const method of ['minutesInDay', 'hasDstInYear', 'isDstTransitionDay']) {
713
+ for (const method of [
714
+ 'minutesInDay',
715
+ 'hasOffsetChangeInYear',
716
+ 'hasOffsetChangeInDay',
717
+ ]) {
763
718
  QronoDate.prototype[method] = function () {
764
719
  return qrono(
765
720
  { disambiguation: 'later' },
@@ -776,24 +731,7 @@ QronoDate.prototype.endOfMonth = function () {
776
731
  return this.clone({ day: this.daysInMonth() })
777
732
  }
778
733
 
779
- QronoDate.prototype.isSame = function (another) {
780
- return +this === +another
781
- }
782
- QronoDate.prototype.isBefore = function (another) {
783
- return this < another
784
- }
785
- QronoDate.prototype.isAfter = function (another) {
786
- return this > another
787
- }
788
- QronoDate.prototype.isSameOrBefore = function (another) {
789
- return this <= another
790
- }
791
- QronoDate.prototype.isSameOrAfter = function (another) {
792
- return this >= another
793
- }
794
- QronoDate.prototype.isBetween = function (a, b) {
795
- return (a <= this && this <= b) || (b <= this && this <= a)
796
- }
734
+ implementComparison(QronoDate.prototype)
797
735
 
798
736
  QronoDate.prototype.plus = function (...args) {
799
737
  return plusDate.call(this, 1, ...args)
package/types/qrono.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { qrono }
1
+ export { qrono }
2
2
 
3
3
  /**
4
4
  * Creates a new Qrono instance.
@@ -217,40 +217,6 @@ declare namespace qrono {
217
217
  */
218
218
  export function context(context: Context): typeof qrono
219
219
 
220
- /**
221
- * Returns whether the global context is localtime.
222
- */
223
- export function localtime(): boolean
224
-
225
- /**
226
- * Sets whether localtime is enabled.
227
- * @param value - True to set the global context localtime.
228
- * @returns The qrono object.
229
- */
230
- export function localtime(value: boolean): typeof qrono
231
-
232
- /**
233
- * Returns the current global disambiguation option.
234
- */
235
- export function disambiguation(): Disambiguation
236
-
237
- /**
238
- * Sets the global disambiguation option.
239
- * @param value - The disambiguation option to set.
240
- * @returns The qrono object.
241
- */
242
- export function disambiguation(value: Disambiguation): typeof qrono
243
-
244
- /**
245
- * Returns new qrono instance with UTC context.
246
- */
247
- export function asUtc(): typeof qrono
248
-
249
- /**
250
- * Returns new qrono instance with localtime context.
251
- */
252
- export function asLocaltime(): typeof qrono
253
-
254
220
  /**
255
221
  * The four disambiguation options for resolving ambiguous local times,
256
222
  * mirroring the Temporal API.
@@ -320,40 +286,11 @@ declare namespace qrono {
320
286
  */
321
287
  offset(): number
322
288
 
323
- /**
324
- * Returns whether localtime is enabled for the Qrono instance.
325
- */
326
- localtime(): boolean
327
-
328
- /**
329
- * Sets whether localtime is enabled for the Qrono instance.
330
- * @param yes - True to enable localtime, false to disable.
331
- * @returns The Qrono instance.
332
- */
333
- localtime(yes: boolean): Qrono
334
-
335
- /**
336
- * Returns the current disambiguation option of the Qrono instance.
337
- */
338
- disambiguation(): Disambiguation
339
-
340
- /**
341
- * Sets the disambiguation option of the Qrono instance.
342
- * @param value - The disambiguation option.
343
- * @returns A new Qrono instance with the updated disambiguation.
344
- */
345
- disambiguation(value: Disambiguation): Qrono
346
-
347
289
  /**
348
290
  * Returns whether the Qrono instance is valid.
349
291
  */
350
292
  valid(): boolean
351
293
 
352
- /**
353
- * Returns the numeric value of the Qrono instance.
354
- */
355
- numeric(): number
356
-
357
294
  /**
358
295
  * Returns the object representation of the Qrono instance.
359
296
  */
@@ -377,18 +314,6 @@ declare namespace qrono {
377
314
  */
378
315
  toDate(): QronoDate
379
316
 
380
- /**
381
- * Sets the context to UTC.
382
- * @returns The Qrono instance.
383
- */
384
- asUtc(): Qrono
385
-
386
- /**
387
- * Sets the context to localtime.
388
- * @returns The Qrono instance.
389
- */
390
- asLocaltime(): Qrono
391
-
392
317
  /**
393
318
  * Returns the year of the Qrono instance.
394
319
  */
@@ -501,7 +426,7 @@ declare namespace qrono {
501
426
  /**
502
427
  * Returns whether the Qrono instance has daylight saving time in the year.
503
428
  */
504
- hasDstInYear(): boolean
429
+ hasOffsetChangeInYear(): boolean
505
430
 
506
431
  /**
507
432
  * Returns whether the Qrono instance is in daylight saving time.
@@ -511,7 +436,7 @@ declare namespace qrono {
511
436
  /**
512
437
  * Returns whether the Qrono instance is on a daylight saving time transition day.
513
438
  */
514
- isDstTransitionDay(): boolean
439
+ hasOffsetChangeInDay(): boolean
515
440
 
516
441
  /**
517
442
  * Returns the number of minutes in the day of the Qrono instance.
@@ -681,11 +606,6 @@ declare namespace qrono {
681
606
  */
682
607
  valid(): boolean
683
608
 
684
- /**
685
- * Returns the numeric value of the QronoDate instance.
686
- */
687
- numeric(): number
688
-
689
609
  /**
690
610
  * Returns the object representation of the QronoDate instance.
691
611
  */
@@ -769,12 +689,12 @@ declare namespace qrono {
769
689
  /**
770
690
  * Returns whether the QronoDate instance has daylight saving time in the year.
771
691
  */
772
- hasDstInYear(): boolean
692
+ hasOffsetChangeInYear(): boolean
773
693
 
774
694
  /**
775
695
  * Returns whether the QronoDate instance is on a daylight saving time transition day.
776
696
  */
777
- isDstTransitionDay(): boolean
697
+ hasOffsetChangeInDay(): boolean
778
698
 
779
699
  /**
780
700
  * Returns the number of minutes in the day of the QronoDate instance.
@@ -806,11 +726,6 @@ declare namespace qrono {
806
726
  */
807
727
  startOfMonth(): QronoDate
808
728
 
809
- /**
810
- * Returns a new QronoDate instance representing the start of the day.
811
- */
812
- startOfDay(): Qrono
813
-
814
729
  /**
815
730
  * Returns a new QronoDate instance representing the end of the year.
816
731
  */