@nivinjoseph/n-date 1.0.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 (43) hide show
  1. package/.editorconfig +14 -0
  2. package/.vscode/launch.json +56 -0
  3. package/.vscode/settings.json +111 -0
  4. package/.vscode/tasks.json +12 -0
  5. package/.yarn/releases/yarn-4.14.1.cjs +940 -0
  6. package/.yarnrc.yml +8 -0
  7. package/LICENSE +21 -0
  8. package/README.md +21 -0
  9. package/dist/date-time-format.d.ts +11 -0
  10. package/dist/date-time-format.d.ts.map +1 -0
  11. package/dist/date-time-format.js +11 -0
  12. package/dist/date-time-format.js.map +1 -0
  13. package/dist/date-time-span.d.ts +70 -0
  14. package/dist/date-time-span.d.ts.map +1 -0
  15. package/dist/date-time-span.js +122 -0
  16. package/dist/date-time-span.js.map +1 -0
  17. package/dist/date-time.d.ts +391 -0
  18. package/dist/date-time.d.ts.map +1 -0
  19. package/dist/date-time.js +753 -0
  20. package/dist/date-time.js.map +1 -0
  21. package/dist/index.d.ts +4 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/tsconfig.json +13 -0
  26. package/docs/README.md +33 -0
  27. package/docs/date-time-span.md +72 -0
  28. package/docs/date-time.md +169 -0
  29. package/docs/formats.md +56 -0
  30. package/docs/getting-started.md +151 -0
  31. package/eslint.config.js +596 -0
  32. package/package.json +57 -0
  33. package/src/date-time-format.ts +35 -0
  34. package/src/date-time-span.ts +130 -0
  35. package/src/date-time.ts +950 -0
  36. package/src/index.ts +3 -0
  37. package/test/date-time-comparison.test.ts +1579 -0
  38. package/test/date-time-create.test.ts +1147 -0
  39. package/test/date-time-math.test.ts +324 -0
  40. package/test/date-time-properties.test.ts +200 -0
  41. package/test/date-time-utility.test.ts +432 -0
  42. package/test/date-time-validations.test.ts +521 -0
  43. package/tsconfig.json +31 -0
@@ -0,0 +1,1147 @@
1
+ import { ArgumentException } from "@nivinjoseph/n-exception";
2
+ import { DateTime as LuxonDateTime } from "luxon";
3
+ import assert from "node:assert";
4
+ import { describe, test } from "node:test";
5
+ import { DateTime, DateTimeFormat_DEFAULT } from "../src/index.js";
6
+
7
+
8
+ await describe("DateTime Create", async () =>
9
+ {
10
+ await describe("Constructor", async () =>
11
+ {
12
+ const validValue = "2024-01-01 10:00:00";
13
+
14
+ function checkIsInvalid(value: string, zone = "utc"): void
15
+ {
16
+ assert.throws(() => new DateTime({ value, zone }), ArgumentException);
17
+ }
18
+
19
+ await test(`Given a valid value and zone
20
+ when the constructor is called
21
+ then it should return a DateTime object`,
22
+ () =>
23
+ {
24
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "utc" }));
25
+ }
26
+ );
27
+
28
+ await test(`Given value as empty string and a valid zone
29
+ when the constructor is called
30
+ then it should throw a validation error`,
31
+ () =>
32
+ {
33
+ checkIsInvalid("");
34
+ }
35
+ );
36
+
37
+ await test(`Given value "2024-01-01 10:60" with an invalid minute and a valid zone
38
+ when the constructor is called
39
+ then it should throw a validation error`,
40
+ () =>
41
+ {
42
+ checkIsInvalid("2024-01-01 10:60");
43
+ }
44
+ );
45
+
46
+ await test(`Given value "2024-01-01 10:0" with an invalid minute format and a valid zone
47
+ when the constructor is called
48
+ then it should throw a validation error`,
49
+ () =>
50
+ {
51
+ checkIsInvalid("2024-01-01 10:0");
52
+ }
53
+ );
54
+
55
+ await test(`Given value "2024-01-01 24:00" with an invalid hour(24) and a valid zone
56
+ when the constructor is called
57
+ then it should throw a validation error`,
58
+ () =>
59
+ {
60
+ checkIsInvalid("2024-01-01 24:00");
61
+ }
62
+ );
63
+
64
+ await test(`Given value "2024-01-01 1:00" with an invalid hour format and a valid zone
65
+ when the constructor is called
66
+ then it should throw a validation error`,
67
+ () =>
68
+ {
69
+ checkIsInvalid("2024-01-01 1:00");
70
+ }
71
+ );
72
+
73
+ await test(`Given value "2024-01-00 10:00" with an invalid day(0) and a valid zone
74
+ when the constructor is called
75
+ then it should throw a validation error`,
76
+ () =>
77
+ {
78
+ checkIsInvalid("2024-01-00 10:00");
79
+ }
80
+ );
81
+
82
+ await test(`Given value "2024-01-32 10:00" with an invalid day(32) and a valid zone
83
+ when the constructor is called
84
+ then it should throw a validation error`,
85
+ () =>
86
+ {
87
+ checkIsInvalid("2024-01-32 10:00");
88
+ }
89
+ );
90
+
91
+ await test(`Given value "2023-02-29 10:00" with an invalid day(february 29 on non-leap year) and a valid zone
92
+ when the constructor is called
93
+ then it should throw a validation error`,
94
+ () =>
95
+ {
96
+ checkIsInvalid("2023-02-29 10:00");
97
+ }
98
+ );
99
+
100
+ await test(`Given value "2024-02-30 10:00" with an invalid day(february 30 on leap year)and a valid zone
101
+ when the constructor is called
102
+ then it should throw a validation error`,
103
+ () =>
104
+ {
105
+ checkIsInvalid("2024-02-30 10:00");
106
+ }
107
+ );
108
+
109
+ await test(`Given value "2024-02-29 10:00" with an valid day(february 29 on leap year) and a valid zone
110
+ when the constructor is called
111
+ then it should return a DateTime object`,
112
+ () =>
113
+ {
114
+ assert.doesNotThrow(() => new DateTime({ value: "2024-02-29 10:00", zone: "utc" }));
115
+ }
116
+ );
117
+
118
+ await test(`Given value "2024-04-31 10:00" with an invalid day(April 31) and a valid zone
119
+ when the constructor is called
120
+ then it should throw a validation error`,
121
+ () =>
122
+ {
123
+ checkIsInvalid("2024-04-31 10:00");
124
+ }
125
+ );
126
+
127
+ await test(`Given value "2024-04-1 10:00" with an invalid day format and a valid zone
128
+ when the constructor is called
129
+ then it should throw a validation error`,
130
+ () =>
131
+ {
132
+ checkIsInvalid("2024-01-1 10:00");
133
+ }
134
+ );
135
+
136
+ await test(`Given value "2024-00-01 10:00" with an invalid month(0) and a valid zone
137
+ when the constructor is called
138
+ then it should throw a validation error`,
139
+ () =>
140
+ {
141
+ checkIsInvalid("2024-00-01 10:00");
142
+ }
143
+ );
144
+
145
+ await test(`Given value "2024-13-01 10:00" with an invalid month(13) and a valid zone
146
+ when the constructor is called
147
+ then it should throw a validation error`,
148
+ () =>
149
+ {
150
+ checkIsInvalid("2024-13-01 10:00");
151
+ }
152
+ );
153
+
154
+ await test(`Given value "2024-1-01 10:00" with an invalid month format and a valid zone
155
+ when the constructor is called
156
+ then it should throw a validation error`,
157
+ () =>
158
+ {
159
+ checkIsInvalid("2024-1-01 10:00");
160
+ }
161
+ );
162
+
163
+ await test(`Given value "24-01-01 10:00" with an invalid year format and a valid zone
164
+ when the constructor is called
165
+ then it should throw a validation error`,
166
+ () =>
167
+ {
168
+ checkIsInvalid("24-01-01 10:00");
169
+ }
170
+ );
171
+
172
+ await test(`Given value "10000-01-01 10:00" with year greater than 9999 and a valid zone
173
+ when the constructor is called
174
+ then it should throw a validation error`,
175
+ () =>
176
+ {
177
+ checkIsInvalid("10000-01-01 10:00");
178
+ }
179
+ );
180
+
181
+ await test(`Given valid value and zone as an empty string
182
+ when the constructor is called
183
+ then it should throw a validation error`,
184
+ () =>
185
+ {
186
+ checkIsInvalid(validValue, "");
187
+ }
188
+ );
189
+
190
+ await test(`Given valid value and zone as an invalid random string
191
+ when the constructor is called
192
+ then it should throw a validation error`,
193
+ () =>
194
+ {
195
+ checkIsInvalid(validValue, "aksfljn");
196
+ }
197
+ );
198
+
199
+ await test(`Given valid value and zone as local
200
+ when the constructor is called
201
+ then it should throw a validation error`,
202
+ () =>
203
+ {
204
+ checkIsInvalid(validValue, "local");
205
+ }
206
+ );
207
+
208
+ await test(`Given valid value and zone as valid IANA zone America/Los_Angeles
209
+ when the constructor is called
210
+ then it should return a DateTime object`,
211
+ () =>
212
+ {
213
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "America/Los_Angeles" }));
214
+ }
215
+ );
216
+
217
+ await test(`Given valid value and zone as invalid IANA zone America/LosAngeles (misspelled)
218
+ when the constructor is called
219
+ then it should throw a validation error`,
220
+ () =>
221
+ {
222
+ checkIsInvalid(validValue, "America/LosAngeles"); // correct is America/Los_Angeles
223
+ }
224
+ );
225
+
226
+ await test(`Given valid value and zone as UTC
227
+ when the constructor is called
228
+ then it should return a DateTime object`,
229
+ () =>
230
+ {
231
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC" }));
232
+ }
233
+ );
234
+
235
+ await test(`Given valid value and zone as valid UTC offset +5:30
236
+ when the constructor is called
237
+ then it should return a DateTime object`,
238
+ () =>
239
+ {
240
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC+5:30" }));
241
+ }
242
+ );
243
+
244
+ await test(`Given valid value and zone as valid UTC offset -3
245
+ when the constructor is called
246
+ then it should return a DateTime object`,
247
+ () =>
248
+ {
249
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC-3" }));
250
+ }
251
+ );
252
+
253
+ await test(`Given valid value and zone as valid UTC offset +14:00
254
+ when the constructor is called
255
+ then it should return a DateTime object`,
256
+ () =>
257
+ {
258
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC+14:00" }));
259
+ }
260
+ );
261
+
262
+ await test(`Given valid value and zone as valid UTC offset -12:00
263
+ when the constructor is called
264
+ then it should return a DateTime object`,
265
+ () =>
266
+ {
267
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC-12:00" }));
268
+ }
269
+ );
270
+
271
+ await test(`Given valid value and zone as valid UTC offset +00:01
272
+ when the constructor is called
273
+ then it should return a DateTime object`,
274
+ () =>
275
+ {
276
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC+00:01" }));
277
+ }
278
+ );
279
+
280
+ await test(`Given valid value and zone as valid UTC offset -00:01
281
+ when the constructor is called
282
+ then it should return a DateTime object`,
283
+ () =>
284
+ {
285
+ assert.doesNotThrow(() => new DateTime({ value: validValue, zone: "UTC-00:01" }));
286
+ }
287
+ );
288
+
289
+ await test(`Given valid value and zone as invalid UTC offset +14:01
290
+ when the constructor is called
291
+ then it should throw a validation error`,
292
+ () =>
293
+ {
294
+ checkIsInvalid(validValue, "UTC+14:01"); // max is +14:00
295
+ }
296
+ );
297
+
298
+ await test(`Given valid value and zone as invalid UTC offset -12:01
299
+ when the constructor is called
300
+ then it should throw a validation error`,
301
+ () =>
302
+ {
303
+ checkIsInvalid(validValue, "UTC-12:01"); // min is -12:00
304
+ }
305
+ );
306
+
307
+ await test(`Given valid value and zone as invalid UTC offset +15
308
+ when the constructor is called
309
+ then it should throw a validation error`,
310
+ () =>
311
+ {
312
+ checkIsInvalid(validValue, "UTC+15"); // max is +14:00
313
+ }
314
+ );
315
+
316
+ await test(`Given valid value and zone as invalid UTC offset -13
317
+ when the constructor is called
318
+ then it should throw a validation error`,
319
+ () =>
320
+ {
321
+ checkIsInvalid(validValue, "UTC-13"); // max is -12:00
322
+ }
323
+ );
324
+ }
325
+ );
326
+
327
+
328
+ await describe("Now", async () =>
329
+ {
330
+ await test(`Given DateTime.now() in default zone (utc)
331
+ when it's compared to Date now in utc
332
+ then it should be same`,
333
+ () =>
334
+ {
335
+ const nativeDate = new Date().toISOString().substring(0, 19).replace("T", " ");
336
+ // this might fail if at the end of minute and next is at start of minute. but rare condition
337
+ assert.strictEqual(DateTime.now().value, nativeDate);
338
+ }
339
+ );
340
+
341
+ await test(`Given DateTime.now() in zone UTC+5:30
342
+ when it's compared to Luxon DateTime now in zone UTC+5:30
343
+ then it should be same`,
344
+ () =>
345
+ {
346
+ // using luxon in this test because native date does not support timezones well
347
+ // this might fail if at the end of minute and next is at start of minute. but rare condition
348
+ assert.strictEqual(DateTime.now("UTC+5:30").value,
349
+ LuxonDateTime.now().setZone("UTC+5:30").toFormat(DateTimeFormat_DEFAULT));
350
+ }
351
+ );
352
+
353
+ await test(`Given DateTime.now() in different zones utc and UTC+5:30
354
+ when the timestamps are compared
355
+ then it should be same`,
356
+ () =>
357
+ {
358
+ // this might fail if at the end of minute and next is at start of minute. but rare condition
359
+ assert.strictEqual(DateTime.now("UTC+5:30").timestamp, DateTime.now().timestamp);
360
+ }
361
+ );
362
+
363
+ await test(`Given zone is not passed in
364
+ when DateTime for now is created with default zone
365
+ then zone property should be utc`,
366
+ () =>
367
+ {
368
+ assert.strictEqual(DateTime.now().zone, "utc");
369
+ }
370
+ );
371
+
372
+ await test(`Given zone as utc
373
+ when DateTime for now is created
374
+ then zone property should be utc`,
375
+ () =>
376
+ {
377
+ assert.strictEqual(DateTime.now("utc").zone, "utc");
378
+ }
379
+ );
380
+
381
+ await test(`Given zone as UTC+5:30
382
+ when DateTime for now is created
383
+ then zone property should be UTC+5:30`,
384
+ () =>
385
+ {
386
+ assert.strictEqual(DateTime.now("UTC+5:30").zone, "UTC+5:30");
387
+ }
388
+ );
389
+
390
+ await test(`Given zone as America/Los_Angeles
391
+ when DateTime for now is created
392
+ then zone property should be America/Los_Angeles`,
393
+ () =>
394
+ {
395
+ assert.strictEqual(DateTime.now("America/Los_Angeles").zone, "America/Los_Angeles");
396
+ }
397
+ );
398
+ });
399
+
400
+
401
+
402
+ await describe("From Timestamp", async () =>
403
+ {
404
+ const timeStamp = 1704103200;// "2024-01-01 10:00"
405
+ const maxTimestamp = 253402300799;// "9999-12-31 23:59:59"
406
+ const minTimestamp = -62167219200;// "0000-01-01 00:00:00"
407
+
408
+ await test(`Given a valid timestamp and zone
409
+ when DateTime is created from that timestamp
410
+ then there should not be any issues`,
411
+ () =>
412
+ {
413
+ assert.doesNotThrow(() => DateTime.createFromTimestamp(timeStamp, "utc"));
414
+ }
415
+ );
416
+
417
+ await test(`Given a valid timestamp for "2024-01-01 10:00:00"
418
+ when DateTime is created from that timestamp
419
+ then value should be "2024-01-01 10:00:00"`,
420
+ () =>
421
+ {
422
+ assert.strictEqual(DateTime.createFromTimestamp(timeStamp, "utc").value, "2024-01-01 10:00:00");
423
+ }
424
+ );
425
+
426
+ await test(`Given a valid timestamp for "2024-01-01 10:00:00"
427
+ when DateTime is created from that timestamp
428
+ then timestamp property should return what's passed in`,
429
+ () =>
430
+ {
431
+ assert.strictEqual(DateTime.createFromTimestamp(timeStamp, "utc").timestamp, timeStamp);
432
+ }
433
+ );
434
+
435
+ await test(`Given timestamp 0 in utc
436
+ when DateTime is created from that timestamp
437
+ the value should be epoch start`,
438
+ () =>
439
+ {
440
+ assert.strictEqual(DateTime.createFromTimestamp(0, "utc").value, "1970-01-01 00:00:00");
441
+ }
442
+ );
443
+
444
+ await test(`Given timestamp -1 in utc
445
+ when DateTime is created from that timestamp
446
+ the value should be epoch start -1 second`,
447
+ () =>
448
+ {
449
+ assert.strictEqual(DateTime.createFromTimestamp(-1, "utc").value, "1969-12-31 23:59:59");
450
+ }
451
+ );
452
+
453
+ await test(`Given a valid timestamp for "9999-12-31 23:59:59"
454
+ when DateTime is created from that timestamp
455
+ then value should be "9999-12-31 23:59:59"`,
456
+ () =>
457
+ {
458
+ assert.strictEqual(DateTime.createFromTimestamp(maxTimestamp, "utc").value, "9999-12-31 23:59:59");
459
+ }
460
+ );
461
+
462
+ await test(`Given a valid timestamp for "0000-01-01 00:00:00"
463
+ when DateTime is created from that timestamp
464
+ then value should be "0000-01-01 00:00:00"`,
465
+ () =>
466
+ {
467
+ assert.strictEqual(DateTime.createFromTimestamp(minTimestamp, "utc").value, "0000-01-01 00:00:00");
468
+ }
469
+ );
470
+
471
+ await test(`Given a timestamp for greater than "9999-12-31 23:59"
472
+ when DateTime is created from that timestamp
473
+ then it should throw a validation error`,
474
+ () =>
475
+ {
476
+ assert.throws(() => DateTime.createFromTimestamp(maxTimestamp + 1, "utc"), ArgumentException);
477
+ }
478
+ );
479
+
480
+ await test(`Given a timestamp for less than "0000-01-01 00:00"
481
+ when DateTime is created from that timestamp
482
+ then it should throw a validation error`,
483
+ () =>
484
+ {
485
+ assert.throws(() => DateTime.createFromTimestamp(minTimestamp - 1, "utc"), ArgumentException);
486
+
487
+ }
488
+ );
489
+
490
+ await test(`Given a valid timestamp and zone as utc
491
+ when DateTime is created from that timestamp
492
+ then zone property should be utc`,
493
+ () =>
494
+ {
495
+ assert.strictEqual(DateTime.createFromTimestamp(timeStamp, "utc").zone, "utc");
496
+ }
497
+ );
498
+
499
+ await test(`Given a valid timestamp and zone as UTC+5:30
500
+ when DateTime is created from that timestamp
501
+ then zone property should be UTC+5:30`,
502
+ () =>
503
+ {
504
+ assert.strictEqual(DateTime.createFromTimestamp(timeStamp, "UTC+5:30").zone, "UTC+5:30");
505
+ }
506
+ );
507
+
508
+ await test(`Given a valid timestamp and zone as America/Los_Angeles
509
+ when DateTime is created from that timestamp
510
+ then zone property should be America/Los_Angeles`,
511
+ () =>
512
+ {
513
+ assert.strictEqual(DateTime.createFromTimestamp(timeStamp, "America/Los_Angeles").zone, "America/Los_Angeles");
514
+ }
515
+ );
516
+ });
517
+
518
+ await describe("From MilliSecondsSinceEpoch", async () =>
519
+ {
520
+ const milliSeconds = 1704103200000; // "2024-01-01 10:00"
521
+ const maxMilliSecondsSinceEpoch = 253402300799999; // "9999-12-31 23:59:59.999"
522
+ const minMilliSecondsSinceEpoch = -62167219200000; // "0000-01-01 00:00:00.000"
523
+
524
+ await test(`Given a valid milliSeconds and zone
525
+ when DateTime is created from that milliSeconds
526
+ then there should not be any issues`,
527
+ () =>
528
+ {
529
+ assert.doesNotThrow(() => DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "utc"));
530
+ }
531
+ );
532
+
533
+ await test(`Given a valid milliSeconds for "2024-01-01 10:00:00"
534
+ when DateTime is created from that milliSeconds
535
+ then value should be "2024-01-01 10:00:00"`,
536
+ () =>
537
+ {
538
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "utc").value, "2024-01-01 10:00:00");
539
+ }
540
+ );
541
+
542
+ await test(`Given a valid milliSeconds for "2024-01-01 10:00:00"
543
+ when DateTime is created from that milliSeconds
544
+ then valueOf() should return what's passed in`,
545
+ () =>
546
+ {
547
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "utc").valueOf(), milliSeconds);
548
+ }
549
+ );
550
+
551
+ await test(`Given milliSeconds 0 in utc
552
+ when DateTime is created from that milliSeconds
553
+ the value should be epoch start`,
554
+ () =>
555
+ {
556
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(0, "utc").value, "1970-01-01 00:00:00");
557
+ }
558
+ );
559
+
560
+ await test(`Given milliSeconds -1 in utc
561
+ when DateTime is created from that milliSeconds
562
+ the value should be epoch start -1 second`,
563
+ () =>
564
+ {
565
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(-1, "utc").value, "1969-12-31 23:59:59");
566
+ }
567
+ );
568
+
569
+ await test(`Given a valid milliSeconds for "9999-12-31 23:59:59"
570
+ when DateTime is created from that milliSeconds
571
+ then value should be "9999-12-31 23:59:59"`,
572
+ () =>
573
+ {
574
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(maxMilliSecondsSinceEpoch, "utc").value,
575
+ "9999-12-31 23:59:59");
576
+ }
577
+ );
578
+
579
+ await test(`Given a valid milliSeconds for "0000-01-01 00:00:00"
580
+ when DateTime is created from that milliSeconds
581
+ then value should be "0000-01-01 00:00:00"`,
582
+ () =>
583
+ {
584
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(minMilliSecondsSinceEpoch, "utc").value,
585
+ "0000-01-01 00:00:00");
586
+ }
587
+ );
588
+
589
+ await test(`Given a milliSeconds for greater than "9999-12-31 23:59:00 999"
590
+ when DateTime is created from that milliSeconds
591
+ then it should throw a validation error`,
592
+ () =>
593
+ {
594
+ assert.throws(() => DateTime.createFromMilliSecondsSinceEpoch(maxMilliSecondsSinceEpoch + 1, "utc"),
595
+ ArgumentException);
596
+ }
597
+ );
598
+
599
+ await test(`Given a milliSeconds for less than "0000-01-01 00:00"
600
+ when DateTime is created from that milliSeconds
601
+ then it should throw a validation error`,
602
+ () =>
603
+ {
604
+ assert.throws(() => DateTime.createFromMilliSecondsSinceEpoch(minMilliSecondsSinceEpoch - 1, "utc"),
605
+ ArgumentException);
606
+
607
+ }
608
+ );
609
+
610
+ await test(`Given a valid milliSeconds and zone as utc
611
+ when DateTime is created from that milliSeconds
612
+ then zone property should be utc`,
613
+ () =>
614
+ {
615
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "utc").zone, "utc");
616
+ }
617
+ );
618
+
619
+ await test(`Given a valid milliSeconds and zone as UTC+5:30
620
+ when DateTime is created from that milliSeconds
621
+ then zone property should be UTC+5:30`,
622
+ () =>
623
+ {
624
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "UTC+5:30").zone, "UTC+5:30");
625
+ }
626
+ );
627
+
628
+ await test(`Given a valid milliSeconds and zone as America/Los_Angeles
629
+ when DateTime is created from that milliSeconds
630
+ then zone property should be America/Los_Angeles`,
631
+ () =>
632
+ {
633
+ assert.strictEqual(DateTime.createFromMilliSecondsSinceEpoch(milliSeconds, "America/Los_Angeles").zone, "America/Los_Angeles");
634
+ }
635
+ );
636
+ });
637
+
638
+ await describe("From Codes", async () =>
639
+ {
640
+ const validDateCode = "20240101";
641
+ const validTimeCode = "100000";
642
+
643
+ function checkIsInvalid(dateCode: string, timeCode: string): void
644
+ {
645
+ assert.throws(() => DateTime.createFromCodes(dateCode, timeCode, "utc"), ArgumentException);
646
+ }
647
+
648
+ await test(`Given a valid date code(20240101), time code(100000) and zone
649
+ when DateTime is created from that codes
650
+ then it should not throw any errors"`,
651
+ () =>
652
+ {
653
+ assert.doesNotThrow(() => DateTime.createFromCodes(validDateCode, validTimeCode, "utc"));
654
+ }
655
+ );
656
+
657
+ await test(`Given a valid date code(20240101), time code(100000) and zone
658
+ when DateTime is created from that codes
659
+ then it should have the value "2024-01-01 10:00:00"`,
660
+ () =>
661
+ {
662
+ assert.strictEqual(DateTime.createFromCodes(validDateCode, validTimeCode, "utc").value, "2024-01-01 10:00:00");
663
+ }
664
+ );
665
+
666
+ await test(`Given a valid time code(100000) and zone, and date code as an empty string
667
+ when DateTime is created from that codes
668
+ then it should throw a validation error`,
669
+ () =>
670
+ {
671
+ checkIsInvalid("", validTimeCode);
672
+ }
673
+ );
674
+
675
+ await test(`Given a valid time code(100000) and zone, and date code is in invalid format 2024-01-01
676
+ when DateTime is created from that codes
677
+ then it should throw a validation error`,
678
+ () =>
679
+ {
680
+ checkIsInvalid("2024-01-01", validTimeCode);
681
+ }
682
+ );
683
+
684
+ await test(`Given a valid time code(100000) and zone, and date code in invalid format 2411
685
+ when DateTime is created from that codes
686
+ then it should throw a validation error`,
687
+ () =>
688
+ {
689
+ checkIsInvalid("2411", validTimeCode);
690
+ }
691
+ );
692
+
693
+ await test(`Given a valid time code(100000) and zone, and date code in invalid format 202411
694
+ when DateTime is created from that codes
695
+ then it should throw a validation error`,
696
+ () =>
697
+ {
698
+ checkIsInvalid("202411", validTimeCode);
699
+ }
700
+ );
701
+
702
+ await test(`Given a valid time code(100000) and zone, and date code in invalid format 2024011
703
+ when DateTime is created from that codes
704
+ then it should throw a validation error`,
705
+ () =>
706
+ {
707
+ checkIsInvalid("2024011", validTimeCode);
708
+ }
709
+ );
710
+
711
+ await test(`Given a valid time code(100000) and zone, and date code in invalid format 2024101
712
+ when DateTime is created from that codes
713
+ then it should throw a validation error`,
714
+ () =>
715
+ {
716
+ checkIsInvalid("2024101", validTimeCode);
717
+ }
718
+ );
719
+
720
+ await test(`Given a valid time code(100000) and zone, and date code in invalid format 240101
721
+ when DateTime is created from that codes
722
+ then it should throw a validation error`,
723
+ () =>
724
+ {
725
+ checkIsInvalid("240101", validTimeCode);
726
+ }
727
+ );
728
+
729
+ await test(`Given a valid time code(100000) and zone, and date code with invalid day 0 20240100
730
+ when DateTime is created from that codes
731
+ then it should throw a validation error`,
732
+ () =>
733
+ {
734
+ checkIsInvalid("20240100", validTimeCode);
735
+ }
736
+ );
737
+
738
+ await test(`Given a valid time code(100000) and zone, and date code with invalid day 32 20240132
739
+ when DateTime is created from that codes
740
+ then it should throw a validation error`,
741
+ () =>
742
+ {
743
+ checkIsInvalid("20240132", validTimeCode);
744
+ }
745
+ );
746
+
747
+ await test(`Given a valid time code(100000) and zone, and date code with invalid day feb 29 on non-leap year 20230229
748
+ when DateTime is created from that codes
749
+ then it should throw a validation error`,
750
+ () =>
751
+ {
752
+ checkIsInvalid("20230229", validTimeCode);
753
+ }
754
+ );
755
+
756
+ await test(`Given a valid time code(100000) and zone, and date code with invalid day feb 30 20240230
757
+ when DateTime is created from that codes
758
+ then it should throw a validation error`,
759
+ () =>
760
+ {
761
+ checkIsInvalid("20240230", validTimeCode);
762
+ }
763
+ );
764
+
765
+ await test(`Given a valid time code(100000) and zone, and date code feb 29 on leap year 20240229
766
+ when DateTime is created from that codes
767
+ then it should return the DateTime object`,
768
+ () =>
769
+ {
770
+ assert.doesNotThrow(() => DateTime.createFromCodes("20240229", validTimeCode, "utc"));
771
+ }
772
+ );
773
+
774
+ await test(`Given a valid time code(100000) and zone, and date code with invalid day 20240431 (April 31)
775
+ when DateTime is created from that codes
776
+ then it should throw a validation error`,
777
+ () =>
778
+ {
779
+ checkIsInvalid("20240431", validTimeCode);
780
+ }
781
+ );
782
+
783
+ await test(`Given a valid time code(100000) and zone, and date code with invalid month 0 20240001
784
+ when DateTime is created from that codes
785
+ then it should throw a validation error`,
786
+ () =>
787
+ {
788
+ checkIsInvalid("20240001", validTimeCode);
789
+ }
790
+ );
791
+
792
+ await test(`Given a valid time code(100000) and zone, and date code with invalid month 13 20241301
793
+ when DateTime is created from that codes
794
+ then it should throw a validation error`,
795
+ () =>
796
+ {
797
+ checkIsInvalid("20241301", validTimeCode);
798
+ }
799
+ );
800
+
801
+ await test(`Given a valid time code(100000) and zone, and date code with invalid year >9999 100000101
802
+ when DateTime is created from that codes
803
+ then it should throw a validation error`,
804
+ () =>
805
+ {
806
+ checkIsInvalid("100000101", validTimeCode);
807
+ }
808
+ );
809
+
810
+ await test(`Given a valid date code(20240101) and zone, and time code as empty string
811
+ when DateTime is created from that codes
812
+ then it should throw a validation error`,
813
+ () =>
814
+ {
815
+ checkIsInvalid(validDateCode, "");
816
+ }
817
+ );
818
+
819
+ await test(`Given a valid date code(20240101) and zone, and time code in invalid format 10:00
820
+ when DateTime is created from that codes
821
+ then it should throw a validation error`,
822
+ () =>
823
+ {
824
+ checkIsInvalid(validDateCode, "10:00");
825
+ }
826
+ );
827
+
828
+ await test(`Given a valid date code(20240101) and zone, and time code in invalid format 001
829
+ when DateTime is created from that codes
830
+ then it should throw a validation error`,
831
+ () =>
832
+ {
833
+ checkIsInvalid(validDateCode, "001");
834
+ }
835
+ );
836
+
837
+ await test(`Given a valid date code(20240101) and zone, and time code in invalid format 10000
838
+ when DateTime is created from that codes
839
+ then it should throw a validation error`,
840
+ () =>
841
+ {
842
+ checkIsInvalid(validDateCode, "10000");
843
+ }
844
+ );
845
+
846
+ await test(`Given a valid date code(20240101) and zone, and time code with invalid minute 1060
847
+ when DateTime is created from that codes
848
+ then it should throw a validation error`,
849
+ () =>
850
+ {
851
+ checkIsInvalid(validDateCode, "1060");
852
+ }
853
+ );
854
+
855
+ await test(`Given a valid date code(20240101) and zone, and time code with invalid hour 2400
856
+ when DateTime is created from that codes
857
+ then it should throw a validation error`,
858
+ () =>
859
+ {
860
+ checkIsInvalid(validDateCode, "2400");
861
+ }
862
+ );
863
+
864
+ await test(`Given a valid date code(20240101), time code(1000) and zone as utc
865
+ when DateTime is created from that codes
866
+ then zone property should be utc`,
867
+ () =>
868
+ {
869
+ assert.strictEqual(DateTime.createFromCodes(validDateCode, validTimeCode, "utc").zone, "utc");
870
+ }
871
+ );
872
+
873
+ await test(`Given a valid date code(20240101), time code(1000) and zone as UTC+5:30
874
+ when DateTime is created from that codes
875
+ then zone property should be UTC+5:30`,
876
+ () =>
877
+ {
878
+ assert.strictEqual(DateTime.createFromCodes(validDateCode, validTimeCode, "UTC+5:30").zone, "UTC+5:30");
879
+ }
880
+ );
881
+
882
+ await test(`Given a valid date code(20240101), time code(100000) and zone as America/Los_Angeles
883
+ when DateTime is created from that codes
884
+ then zone property should be America/Los_Angeles`,
885
+ () =>
886
+ {
887
+ assert.strictEqual(DateTime.createFromCodes(validDateCode, validTimeCode, "America/Los_Angeles").zone, "America/Los_Angeles");
888
+ }
889
+ );
890
+ });
891
+
892
+
893
+ await describe("From values", async () =>
894
+ {
895
+ const validDateValue = "2024-01-01";
896
+ const validTimeValue = "10:00:00";
897
+
898
+ function checkIsInvalid(dateValue: string, timeValue: string): void
899
+ {
900
+ assert.throws(() => DateTime.createFromValues(dateValue, timeValue, "utc"), ArgumentException);
901
+ }
902
+
903
+ await test(`Given a valid date value(2024-01-01), time value(10:00:00) and zone
904
+ when DateTime is created from that values
905
+ then it should have the value "2024-01-01 10:00:00"`,
906
+ () =>
907
+ {
908
+ assert.strictEqual(DateTime.createFromValues(validDateValue, validTimeValue, "utc").value, "2024-01-01 10:00:00");
909
+ }
910
+ );
911
+
912
+ await test(`Given a valid time value(10:00:00) and zone, and date value as an empty string
913
+ when DateTime is created from that values
914
+ then it should throw a validation error`,
915
+ () =>
916
+ {
917
+ checkIsInvalid("", validTimeValue);
918
+ }
919
+ );
920
+
921
+ await test(`Given a valid time value(10:00:00) and zone, and date value in incorrect format "2024/01/01"
922
+ when DateTime is created from that values
923
+ then it should throw a validation error`,
924
+ () =>
925
+ {
926
+ checkIsInvalid("2024/01/01", validTimeValue);
927
+ }
928
+ );
929
+
930
+ await test(`Given a valid time value(10:00:00) and zone, and date value in invalid format 24-1-1
931
+ when DateTime is created from that values
932
+ then it should throw a validation error`,
933
+ () =>
934
+ {
935
+ checkIsInvalid("24-1-1", validTimeValue);
936
+ }
937
+ );
938
+
939
+ await test(`Given a valid time value(10:00) and zone, and date value in invalid format 2024-1-1
940
+ when DateTime is created from that values
941
+ then it should throw a validation error`,
942
+ () =>
943
+ {
944
+ checkIsInvalid("2024-1-1", validTimeValue);
945
+ }
946
+ );
947
+
948
+ await test(`Given a valid time value(10:00:00) and zone, and date value in invalid format 2024-01-1
949
+ when DateTime is created from that values
950
+ then it should throw a validation error`,
951
+ () =>
952
+ {
953
+ checkIsInvalid("2024-01-1", validTimeValue);
954
+ }
955
+ );
956
+
957
+ await test(`Given a valid time value(10:00:00) and zone, and date value in invalid format 2024-1-01
958
+ when DateTime is created from that values
959
+ then it should throw a validation error`,
960
+ () =>
961
+ {
962
+ checkIsInvalid("2024-1-01", validTimeValue);
963
+ }
964
+ );
965
+
966
+ await test(`Given a valid time value(10:00:00) and zone, and date value in invalid format 24-01-01
967
+ when DateTime is created from that values
968
+ then it should throw a validation error`,
969
+ () =>
970
+ {
971
+ checkIsInvalid("24-01-01", validTimeValue);
972
+ }
973
+ );
974
+
975
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid day 0 2024-01-00
976
+ when DateTime is created from that values
977
+ then it should throw a validation error`,
978
+ () =>
979
+ {
980
+ checkIsInvalid("2024-01-00", validTimeValue);
981
+ }
982
+ );
983
+
984
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid day 32 2024-01-32
985
+ when DateTime is created from that values
986
+ then it should throw a validation error`,
987
+ () =>
988
+ {
989
+ checkIsInvalid("2024-01-32", validTimeValue);
990
+ }
991
+ );
992
+
993
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid day feb 29 on non-leap year 2023-02-29
994
+ when DateTime is created from that values
995
+ then it should throw a validation error`,
996
+ () =>
997
+ {
998
+ checkIsInvalid("2023-02-29", validTimeValue);
999
+ }
1000
+ );
1001
+
1002
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid day feb 30 2024-02-30
1003
+ when DateTime is created from that values
1004
+ then it should throw a validation error`,
1005
+ () =>
1006
+ {
1007
+ checkIsInvalid("2024-02-30", validTimeValue);
1008
+ }
1009
+ );
1010
+
1011
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid day 2024-04-31 (April 31)
1012
+ when DateTime is created from that values
1013
+ then it should throw a validation error`,
1014
+ () =>
1015
+ {
1016
+ checkIsInvalid("2024-04-31", validTimeValue);
1017
+ }
1018
+ );
1019
+
1020
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid month 0 2024-00-01
1021
+ when DateTime is created from that values
1022
+ then it should throw a validation error`,
1023
+ () =>
1024
+ {
1025
+ checkIsInvalid("2024-00-01", validTimeValue);
1026
+ }
1027
+ );
1028
+
1029
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid month 13 2024-13-01
1030
+ when DateTime is created from that values
1031
+ then it should throw a validation error`,
1032
+ () =>
1033
+ {
1034
+ checkIsInvalid("2024-13-01", validTimeValue);
1035
+ }
1036
+ );
1037
+
1038
+ await test(`Given a valid time value(10:00:00) and zone, and date value with invalid year >9999 10000-01-01
1039
+ when DateTime is created from that values
1040
+ then it should throw a validation error`,
1041
+ () =>
1042
+ {
1043
+ checkIsInvalid("10000-01-01", validTimeValue);
1044
+ }
1045
+ );
1046
+
1047
+ await test(`Given a valid date value(2024-01-01) and zone, and time value as empty string
1048
+ when DateTime is created from that values
1049
+ then it should throw a validation error`,
1050
+ () =>
1051
+ {
1052
+ checkIsInvalid(validDateValue, "");
1053
+ }
1054
+ );
1055
+
1056
+ await test(`Given a valid date value(2024-01-01) and zone, and time value in invalid format 10.00
1057
+ when DateTime is created from that values
1058
+ then it should throw a validation error`,
1059
+ () =>
1060
+ {
1061
+ checkIsInvalid(validDateValue, "10.00");
1062
+ }
1063
+ );
1064
+
1065
+ await test(`Given a valid date value(2024-01-01) and zone, and time value in invalid format 1000
1066
+ when DateTime is created from that values
1067
+ then it should throw a validation error`,
1068
+ () =>
1069
+ {
1070
+ checkIsInvalid(validDateValue, "1000");
1071
+ }
1072
+ );
1073
+
1074
+ await test(`Given a valid date value(2024-01-01) and zone, and time value in invalid format 00:1
1075
+ when DateTime is created from that values
1076
+ then it should throw a validation error`,
1077
+ () =>
1078
+ {
1079
+ checkIsInvalid(validDateValue, "00:1");
1080
+ }
1081
+ );
1082
+
1083
+ await test(`Given a valid date value(2024-01-01) and zone, and time value in invalid format 100:00
1084
+ when DateTime is created from that values
1085
+ then it should throw a validation error`,
1086
+ () =>
1087
+ {
1088
+ checkIsInvalid(validDateValue, "100:00");
1089
+ }
1090
+ );
1091
+
1092
+ await test(`Given a valid date value(2024-01-01) and zone, and time value with invalid minute 10:60
1093
+ when DateTime is created from that values
1094
+ then it should throw a validation error`,
1095
+ () =>
1096
+ {
1097
+ checkIsInvalid(validDateValue, "10:60");
1098
+ }
1099
+ );
1100
+
1101
+ await test(`Given a valid date value(2024-01-01) and zone, and time value with invalid hour 24:00
1102
+ when DateTime is created from that values
1103
+ then it should throw a validation error`,
1104
+ () =>
1105
+ {
1106
+ checkIsInvalid(validDateValue, "24:00");
1107
+ }
1108
+ );
1109
+
1110
+ await test(`Given a valid time value(10:00) and zone, and date value feb 29 on leap year 2024-02-29
1111
+ when DateTime is created from that values
1112
+ then it should return the DateTime object`,
1113
+ () =>
1114
+ {
1115
+ assert.doesNotThrow(() => DateTime.createFromValues("2024-02-29", validTimeValue, "utc"));
1116
+ }
1117
+ );
1118
+
1119
+ await test(`Given a valid date value(2024-01-01), time value(10:00) and zone as utc
1120
+ when DateTime is created from that values
1121
+ then zone property should be utc`,
1122
+ () =>
1123
+ {
1124
+ assert.strictEqual(DateTime.createFromValues(validDateValue, validTimeValue, "utc").zone, "utc");
1125
+ }
1126
+ );
1127
+
1128
+ await test(`Given a valid date value(2024-01-01), time value(10:00) and zone as UTC+5:30
1129
+ when DateTime is created from that values
1130
+ then zone property should be UTC+5:30`,
1131
+ () =>
1132
+ {
1133
+ assert.strictEqual(DateTime.createFromValues(validDateValue, validTimeValue, "UTC+5:30").zone, "UTC+5:30");
1134
+ }
1135
+ );
1136
+
1137
+ await test(`Given a valid date value(2024-01-01), time value(10:00) and zone as America/Los_Angeles
1138
+ when DateTime is created from that values
1139
+ then zone property should be America/Los_Angeles`,
1140
+ () =>
1141
+ {
1142
+ assert.strictEqual(DateTime.createFromValues(validDateValue, validTimeValue, "America/Los_Angeles").zone, "America/Los_Angeles");
1143
+ }
1144
+ );
1145
+ });
1146
+ });
1147
+