@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,1579 @@
1
+ import { given } from "@nivinjoseph/n-defensive";
2
+ import { ArgumentException } from "@nivinjoseph/n-exception";
3
+ import assert from "node:assert";
4
+ import { describe, test } from "node:test";
5
+ import { DateTime, DateTimeFormat_DEFAULT } from "../src/index.js";
6
+ import { Duration } from "@nivinjoseph/n-util";
7
+
8
+
9
+ await describe("DateTime Comparison", async () =>
10
+ {
11
+
12
+ async function testDifferentSetOfValues(compareFunction: (minValue: string, maxValue: string, diff: string,
13
+ timeDiff: Duration, daysDiff: number) => Promise<void>): Promise<void>
14
+ {
15
+ // Compare different minutes in same zone
16
+ await compareFunction(
17
+ "2024-01-01 10:00:00",
18
+ "2024-01-01 10:01:00",
19
+ "1 minute",
20
+ Duration.fromMinutes(1),
21
+ 0
22
+ );
23
+
24
+ // Compare different hours in same zone
25
+ await compareFunction(
26
+ "2024-01-01 10:00:00",
27
+ "2024-01-01 11:00:00",
28
+ "1 hour",
29
+ Duration.fromHours(1),
30
+ 0
31
+ );
32
+
33
+ // Compare different days in same zone
34
+ await compareFunction(
35
+ "2024-01-01 10:00:00",
36
+ "2024-01-02 10:00:00",
37
+ "1 day",
38
+ Duration.fromDays(1),
39
+ 1
40
+ );
41
+
42
+ // Compare different months in same zone
43
+ await compareFunction(
44
+ "2024-01-01 10:00:00",
45
+ "2024-02-01 10:00:00",
46
+ "1 month",
47
+ Duration.fromDays(31),
48
+ 31
49
+ );
50
+
51
+ // Compare different years in same zone
52
+ await compareFunction(
53
+ "2023-01-01 10:00:00",
54
+ "2024-01-01 10:00:00",
55
+ "1 year",
56
+ Duration.fromDays(365),
57
+ 365
58
+ );
59
+
60
+ // Compare different years (leap year) in same zone
61
+ await compareFunction(
62
+ "2024-01-01 10:00:00",
63
+ "2025-01-01 10:00:00",
64
+ "1 year",
65
+ Duration.fromDays(366),
66
+ 366
67
+ );
68
+ }
69
+
70
+
71
+ async function testDifferentZones(compareFunction: (value: string, behindZone: string, aheadZone: string, diff: string,
72
+ timeDiff: Duration, daysDiff: number) => Promise<void>): Promise<void>
73
+ {
74
+ // Compare same value but different zones utc and IST (UTC+5:30)
75
+ await compareFunction(
76
+ "2024-01-01 10:00:00",
77
+ "utc",
78
+ "UTC+5:30",
79
+ "5 hour 30 minute",
80
+ Duration.fromHours(5.5),
81
+ 0
82
+ );
83
+
84
+ // Compare same value but different zones America/Los_Angeles and utc
85
+ // could be 7 or 8 based on Daylight savings
86
+ await compareFunction(
87
+ "2024-01-01 10:00:00",
88
+ "America/Los_Angeles",
89
+ "utc",
90
+ `8 hours`,
91
+ Duration.fromHours(8),
92
+ 0
93
+ );
94
+
95
+ // Compare same value but different zones America/Los_Angeles and IST(UTC+5:30)
96
+ // could be 12.5 or 13.5 based on Daylight savings
97
+ await compareFunction(
98
+ "2024-01-01 10:00:00",
99
+ "America/Los_Angeles",
100
+ "UTC+5:30",
101
+ `13 hours 30 minutes`,
102
+ Duration.fromHours(13.5),
103
+ 0
104
+ );
105
+
106
+ await compareFunction(
107
+ "2024-06-01 10:00:00",
108
+ "America/Los_Angeles",
109
+ "UTC+5:30",
110
+ `12 hours 30 minutes`,
111
+ Duration.fromHours(12.5),
112
+ 0
113
+ );
114
+ }
115
+
116
+
117
+ async function testSameTimestampDifferentValueAndZone(compareFunction: (dateTime1: DateTime, dateTime2: DateTime) => Promise<void>): Promise<void>
118
+ {
119
+ const utcDateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
120
+
121
+ // Compare different value and zones utc and IST but represent same time
122
+ await compareFunction(
123
+ utcDateTime,
124
+ utcDateTime.convertToZone("UTC+5:30")
125
+ );
126
+
127
+ // Compare different value and zones America/Los_Angeles and utc but represent same time
128
+ await compareFunction(
129
+ utcDateTime,
130
+ utcDateTime.convertToZone("America/Los_Angeles")
131
+ );
132
+
133
+ // Compare different value and zones America/Los_Angeles and utc but represent same time
134
+ await compareFunction(
135
+ utcDateTime.convertToZone("UTC+5:30"),
136
+ utcDateTime.convertToZone("America/Los_Angeles")
137
+ );
138
+ }
139
+
140
+ await describe("DateTime.min", async () =>
141
+ {
142
+ await test(`Given the same DateTime object
143
+ when it's compared with DateTime.min
144
+ then it should return the min DateTime object`,
145
+ () =>
146
+ {
147
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
148
+ assert.strictEqual(DateTime.min(dateTime, dateTime), dateTime); // return second arg when same
149
+ }
150
+ );
151
+
152
+ await test(`Given two DateTime object with same value and zone
153
+ when it's compared with DateTime.min
154
+ then it should return the second dateTime that's passed in`,
155
+ () =>
156
+ {
157
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
158
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
159
+
160
+ assert.strictEqual(DateTime.min(dateTime1, dateTime2), dateTime2); // return second arg when same
161
+ assert.strictEqual(DateTime.min(dateTime2, dateTime1), dateTime1); // return second arg when same
162
+ }
163
+ );
164
+
165
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
166
+ {
167
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
168
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
169
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
170
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
171
+ given(diff, "diff").ensureHasValue().ensureIsString();
172
+
173
+ const min = new DateTime({ value: minValue, zone: "utc" });
174
+ const max = new DateTime({ value: maxValue, zone: "utc" });
175
+
176
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
177
+ when it's compared with DateTime.min
178
+ then it should return the one with value ${minValue}`,
179
+ () =>
180
+ {
181
+ assert.strictEqual(DateTime.min(min, max), min);
182
+ assert.strictEqual(DateTime.min(max, min), min);
183
+ }
184
+ );
185
+ }
186
+
187
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
188
+
189
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
190
+ {
191
+ given(value, "value").ensureHasValue().ensureIsString()
192
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
193
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
194
+ .ensure(t => DateTime.validateTimeZone(t));
195
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
196
+ .ensure(t => DateTime.validateTimeZone(t));
197
+ given(diff, "diff").ensureHasValue().ensureIsString();
198
+
199
+ const min = new DateTime({ value, zone: aheadZone });
200
+ const max = new DateTime({ value, zone: behindZone });
201
+
202
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
203
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
204
+
205
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
206
+ when it's compared with DateTime.min
207
+ then it should return the one with zone ${aheadZone}`,
208
+ () =>
209
+ {
210
+ assert.strictEqual(DateTime.min(min, max), min);
211
+ assert.strictEqual(DateTime.min(max, min), min);
212
+ }
213
+ );
214
+ }
215
+
216
+ await testDifferentZones(compareDateTimeWithDifferentZones);
217
+
218
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
219
+ {
220
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
221
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
222
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
223
+
224
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
225
+ when it's compared with DateTime.min
226
+ then it should return the second dateTime that's passed in`,
227
+ () =>
228
+ {
229
+ assert.strictEqual(DateTime.min(dateTime1, dateTime2), dateTime2); // return second arg when same
230
+ assert.strictEqual(DateTime.min(dateTime2, dateTime1), dateTime1); // return second arg when same
231
+ }
232
+ );
233
+ }
234
+
235
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
236
+ });
237
+
238
+ await describe("DateTime.max", async () =>
239
+ {
240
+ await test(`Given the same DateTime object
241
+ when it's compared with DateTime.max
242
+ then it should return the max DateTime object`,
243
+ () =>
244
+ {
245
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
246
+ assert.strictEqual(DateTime.max(dateTime, dateTime), dateTime); // return second arg when same
247
+ }
248
+ );
249
+
250
+ await test(`Given two DateTime object with same value and zone
251
+ when it's compared with DateTime.max
252
+ then it should return the second dateTime that's passed in`,
253
+ () =>
254
+ {
255
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
256
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
257
+
258
+ assert.strictEqual(DateTime.max(dateTime1, dateTime2), dateTime2); // return second arg when same
259
+ assert.strictEqual(DateTime.max(dateTime2, dateTime1), dateTime1); // return second arg when same
260
+ }
261
+ );
262
+
263
+
264
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
265
+ {
266
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
267
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
268
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
269
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
270
+ given(diff, "diff").ensureHasValue().ensureIsString();
271
+
272
+ const min = new DateTime({ value: minValue, zone: "utc" });
273
+ const max = new DateTime({ value: maxValue, zone: "utc" });
274
+
275
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
276
+ when it's compared with DateTime.max
277
+ then it should return the one with value ${maxValue}`,
278
+ () =>
279
+ {
280
+ assert.strictEqual(DateTime.max(min, max), max);
281
+ assert.strictEqual(DateTime.max(max, min), max);
282
+ }
283
+ );
284
+ }
285
+
286
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
287
+
288
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
289
+ {
290
+ given(value, "value").ensureHasValue().ensureIsString()
291
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
292
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
293
+ .ensure(t => DateTime.validateTimeZone(t));
294
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
295
+ .ensure(t => DateTime.validateTimeZone(t));
296
+ given(diff, "diff").ensureHasValue().ensureIsString();
297
+
298
+ const min = new DateTime({ value, zone: aheadZone });
299
+ const max = new DateTime({ value, zone: behindZone });
300
+
301
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
302
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
303
+
304
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
305
+ when it's compared with DateTime.max
306
+ then it should return the one with zone ${aheadZone}`,
307
+ () =>
308
+ {
309
+ assert.strictEqual(DateTime.max(min, max), max);
310
+ assert.strictEqual(DateTime.max(max, min), max);
311
+ }
312
+ );
313
+ }
314
+
315
+ await testDifferentZones(compareDateTimeWithDifferentZones);
316
+
317
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
318
+ {
319
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
320
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
321
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
322
+
323
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
324
+ when it's compared with DateTime.max
325
+ then it should return the second dateTime that's passed in`,
326
+ () =>
327
+ {
328
+ assert.strictEqual(DateTime.max(dateTime1, dateTime2), dateTime2); // return second arg when same
329
+ assert.strictEqual(DateTime.max(dateTime2, dateTime1), dateTime1); // return second arg when same
330
+ }
331
+ );
332
+ }
333
+
334
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
335
+ });
336
+
337
+ await describe("DateTime Is Same", async () =>
338
+ {
339
+ await test(`Given the same DateTime object
340
+ when it's checked one is same as the other
341
+ then it should return true`,
342
+ () =>
343
+ {
344
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
345
+ assert.ok(dateTime.isSame(dateTime));
346
+ }
347
+ );
348
+
349
+ await test(`Given two DateTime object with same value and zone
350
+ when it's checked one is same as the other
351
+ then it should return true`,
352
+ () =>
353
+ {
354
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
355
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
356
+
357
+ assert.ok(dateTime1.isSame(dateTime2));
358
+ assert.ok(dateTime2.isSame(dateTime1));
359
+ }
360
+ );
361
+
362
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
363
+ {
364
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
365
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
366
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
367
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
368
+ given(diff, "diff").ensureHasValue().ensureIsString();
369
+
370
+ const min = new DateTime({ value: minValue, zone: "utc" });
371
+ const max = new DateTime({ value: maxValue, zone: "utc" });
372
+
373
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
374
+ when it's checked one is same as the other
375
+ then it should return false`,
376
+ () =>
377
+ {
378
+ assert.ok(!min.isSame(max));
379
+ assert.ok(!max.isSame(min));
380
+ }
381
+ );
382
+ }
383
+
384
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
385
+
386
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
387
+ {
388
+ given(value, "value").ensureHasValue().ensureIsString()
389
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
390
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
391
+ .ensure(t => DateTime.validateTimeZone(t));
392
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
393
+ .ensure(t => DateTime.validateTimeZone(t));
394
+ given(diff, "diff").ensureHasValue().ensureIsString();
395
+
396
+ const min = new DateTime({ value, zone: aheadZone });
397
+ const max = new DateTime({ value, zone: behindZone });
398
+
399
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
400
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
401
+
402
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
403
+ when it's checked one is same as the other
404
+ then it should return false`,
405
+ () =>
406
+ {
407
+ assert.ok(!min.isSame(max));
408
+ assert.ok(!max.isSame(min));
409
+ }
410
+ );
411
+ }
412
+
413
+ await testDifferentZones(compareDateTimeWithDifferentZones);
414
+
415
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
416
+ {
417
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
418
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
419
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
420
+
421
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
422
+ when it's checked one is same as the other
423
+ then it should return true`,
424
+ () =>
425
+ {
426
+ assert.ok(dateTime1.isSame(dateTime2));
427
+ assert.ok(dateTime2.isSame(dateTime1));
428
+ }
429
+ );
430
+ }
431
+
432
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
433
+ });
434
+
435
+ await describe("DateTime Is Same Day", async () =>
436
+ {
437
+ await test(`Given the same DateTime object
438
+ when checking if they are on the same day
439
+ then it should return true`,
440
+ () =>
441
+ {
442
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
443
+ assert.ok(dateTime.isSameDay(dateTime));
444
+ }
445
+ );
446
+
447
+ await test(`Given two DateTime object with same value and zone
448
+ when checking if they are on the same day
449
+ then it should return true`,
450
+ () =>
451
+ {
452
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
453
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
454
+
455
+ assert.ok(dateTime1.isSameDay(dateTime2));
456
+ assert.ok(dateTime2.isSameDay(dateTime1));
457
+ }
458
+ );
459
+
460
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string,
461
+ _: Duration, daysDiff: number): Promise<void>
462
+ {
463
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
464
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
465
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
466
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
467
+ given(diff, "diff").ensureHasValue().ensureIsString();
468
+ given(daysDiff, "daysDiff").ensureHasValue().ensureIsNumber().ensure(t => t >= 0);
469
+
470
+ const min = new DateTime({ value: minValue, zone: "utc" });
471
+ const max = new DateTime({ value: maxValue, zone: "utc" });
472
+
473
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
474
+ when checking if they are on the same day
475
+ then it should return ${daysDiff > 0}`,
476
+ () =>
477
+ {
478
+ assert.ok(daysDiff > 0 ? !min.isSameDay(max) : min.isSameDay(max));
479
+ assert.ok(daysDiff > 0 ? !max.isSameDay(min) : max.isSameDay(min));
480
+ }
481
+ );
482
+ }
483
+
484
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
485
+
486
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string,
487
+ _: Duration, daysDiff: number): Promise<void>
488
+ {
489
+ given(value, "value").ensureHasValue().ensureIsString()
490
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
491
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
492
+ .ensure(t => DateTime.validateTimeZone(t));
493
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
494
+ .ensure(t => DateTime.validateTimeZone(t));
495
+ given(diff, "diff").ensureHasValue().ensureIsString();
496
+
497
+ const min = new DateTime({ value, zone: aheadZone });
498
+ const max = new DateTime({ value, zone: behindZone });
499
+
500
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
501
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
502
+
503
+
504
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
505
+ when checking if they are on the same day
506
+ then it should return ${daysDiff > 0}`,
507
+ () =>
508
+ {
509
+ assert.ok(daysDiff > 0 ? !min.isSameDay(max) : min.isSameDay(max));
510
+ assert.ok(daysDiff > 0 ? !max.isSameDay(min) : max.isSameDay(min));
511
+ }
512
+ );
513
+ }
514
+
515
+ await testDifferentZones(compareDateTimeWithDifferentZones);
516
+
517
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
518
+ {
519
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
520
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
521
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
522
+
523
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
524
+ when checking if they are on the same day
525
+ then it should return true`,
526
+ () =>
527
+ {
528
+ assert.ok(dateTime1.isSameDay(dateTime2));
529
+ assert.ok(dateTime2.isSameDay(dateTime1));
530
+ }
531
+ );
532
+ }
533
+
534
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
535
+ });
536
+
537
+ await describe("DateTime Is Equals", async () =>
538
+ {
539
+ await test(`Given the same DateTime object
540
+ when it's checked one equals the other
541
+ then it should return true`,
542
+ () =>
543
+ {
544
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
545
+ assert.ok(dateTime.equals(dateTime));
546
+ }
547
+ );
548
+
549
+ await test(`Given two DateTime object with same value and zone
550
+ when it's checked one equals the other
551
+ then it should return true`,
552
+ () =>
553
+ {
554
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
555
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
556
+
557
+ assert.ok(dateTime1.equals(dateTime2));
558
+ assert.ok(dateTime2.equals(dateTime1));
559
+ }
560
+ );
561
+
562
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
563
+ {
564
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
565
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
566
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
567
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
568
+ given(diff, "diff").ensureHasValue().ensureIsString();
569
+
570
+ const min = new DateTime({ value: minValue, zone: "utc" });
571
+ const max = new DateTime({ value: maxValue, zone: "utc" });
572
+
573
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
574
+ when it's checked one equals the other
575
+ then it should return false`,
576
+ () =>
577
+ {
578
+ assert.ok(!min.equals(max));
579
+ assert.ok(!max.equals(min));
580
+ }
581
+ );
582
+ }
583
+
584
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
585
+
586
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
587
+ {
588
+ given(value, "value").ensureHasValue().ensureIsString()
589
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
590
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
591
+ .ensure(t => DateTime.validateTimeZone(t));
592
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
593
+ .ensure(t => DateTime.validateTimeZone(t));
594
+ given(diff, "diff").ensureHasValue().ensureIsString();
595
+
596
+ const min = new DateTime({ value, zone: aheadZone });
597
+ const max = new DateTime({ value, zone: behindZone });
598
+
599
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
600
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
601
+
602
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
603
+ when it's checked one equals the other
604
+ then it should return false`,
605
+ () =>
606
+ {
607
+ assert.ok(!min.equals(max));
608
+ assert.ok(!max.equals(min));
609
+ }
610
+ );
611
+ }
612
+
613
+ await testDifferentZones(compareDateTimeWithDifferentZones);
614
+
615
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
616
+ {
617
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
618
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
619
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
620
+
621
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
622
+ when it's checked one equals the other
623
+ then it should return false`,
624
+ () =>
625
+ {
626
+ assert.ok(!dateTime1.equals(dateTime2));
627
+ assert.ok(!dateTime2.equals(dateTime1));
628
+ }
629
+ );
630
+ }
631
+
632
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
633
+ });
634
+
635
+ await describe("DateTime Is Before", async () =>
636
+ {
637
+ await test(`Given the same DateTime object
638
+ when it's checked one is before the other
639
+ then it should return false`,
640
+ () =>
641
+ {
642
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
643
+ assert.ok(!dateTime.isBefore(dateTime));
644
+ }
645
+ );
646
+
647
+ await test(`Given two DateTime object with same value and zone
648
+ when it's checked one is before the other
649
+ then it should return false`,
650
+ () =>
651
+ {
652
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
653
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
654
+
655
+ assert.ok(!dateTime1.isBefore(dateTime2));
656
+ assert.ok(!dateTime2.isBefore(dateTime1));
657
+ }
658
+ );
659
+
660
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
661
+ {
662
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
663
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
664
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
665
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
666
+ given(diff, "diff").ensureHasValue().ensureIsString();
667
+
668
+ const min = new DateTime({ value: minValue, zone: "utc" });
669
+ const max = new DateTime({ value: maxValue, zone: "utc" });
670
+
671
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
672
+ when it's checked dateTime with value ${minValue} is before the dateTime with value ${maxValue}
673
+ then it should return true`,
674
+ () =>
675
+ {
676
+ assert.ok(min.isBefore(max));
677
+ }
678
+ );
679
+
680
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
681
+ when it's checked dateTime with value ${maxValue} is before the dateTime with value ${minValue}
682
+ then it should return false`,
683
+ () =>
684
+ {
685
+ assert.ok(!max.isBefore(min));
686
+ }
687
+ );
688
+ }
689
+
690
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
691
+
692
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
693
+ {
694
+ given(value, "value").ensureHasValue().ensureIsString()
695
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
696
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
697
+ .ensure(t => DateTime.validateTimeZone(t));
698
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
699
+ .ensure(t => DateTime.validateTimeZone(t));
700
+ given(diff, "diff").ensureHasValue().ensureIsString();
701
+
702
+ const min = new DateTime({ value, zone: aheadZone });
703
+ const max = new DateTime({ value, zone: behindZone });
704
+
705
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
706
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
707
+
708
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
709
+ when it's checked dateTime with zone ${aheadZone} is before the dateTime with zone ${behindZone}
710
+ then it should return true`,
711
+ () =>
712
+ {
713
+ assert.ok(min.isBefore(max));
714
+ }
715
+ );
716
+
717
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
718
+ when it's checked dateTime with zone ${behindZone} is before the dateTime with zone ${aheadZone}
719
+ then it should return false`,
720
+ () =>
721
+ {
722
+ assert.ok(!max.isBefore(min));
723
+ }
724
+ );
725
+ }
726
+
727
+ await testDifferentZones(compareDateTimeWithDifferentZones);
728
+
729
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
730
+ {
731
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
732
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
733
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
734
+
735
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
736
+ when it's checked one is before the other
737
+ then it should return false`,
738
+ () =>
739
+ {
740
+ assert.ok(!dateTime1.isBefore(dateTime2));
741
+ assert.ok(!dateTime2.isBefore(dateTime1));
742
+ }
743
+ );
744
+ }
745
+
746
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
747
+ });
748
+
749
+ await describe("DateTime Is Same or Before", async () =>
750
+ {
751
+ await test(`Given the same DateTime object
752
+ when it's checked one is same or before the other
753
+ then it should return true`,
754
+ () =>
755
+ {
756
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
757
+ assert.ok(dateTime.isSameOrBefore(dateTime));
758
+ }
759
+ );
760
+
761
+ await test(`Given two DateTime object with same value and zone
762
+ when it's checked one is same or before the other
763
+ then it should return true`,
764
+ () =>
765
+ {
766
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
767
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
768
+
769
+ assert.ok(dateTime1.isSameOrBefore(dateTime2));
770
+ assert.ok(dateTime2.isSameOrBefore(dateTime1));
771
+ }
772
+ );
773
+
774
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
775
+ {
776
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
777
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
778
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
779
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
780
+ given(diff, "diff").ensureHasValue().ensureIsString();
781
+
782
+ const min = new DateTime({ value: minValue, zone: "utc" });
783
+ const max = new DateTime({ value: maxValue, zone: "utc" });
784
+
785
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
786
+ when it's checked dateTime with value ${minValue} is same or before the dateTime with value ${maxValue}
787
+ then it should return true`,
788
+ () =>
789
+ {
790
+ assert.ok(min.isSameOrBefore(max));
791
+ }
792
+ );
793
+
794
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
795
+ when it's checked dateTime with value ${maxValue} is same or before the dateTime with value ${minValue}
796
+ then it should return false`,
797
+ () =>
798
+ {
799
+ assert.ok(!max.isSameOrBefore(min));
800
+ }
801
+ );
802
+ }
803
+
804
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
805
+
806
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
807
+ {
808
+ given(value, "value").ensureHasValue().ensureIsString()
809
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
810
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
811
+ .ensure(t => DateTime.validateTimeZone(t));
812
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
813
+ .ensure(t => DateTime.validateTimeZone(t));
814
+ given(diff, "diff").ensureHasValue().ensureIsString();
815
+
816
+ const min = new DateTime({ value, zone: aheadZone });
817
+ const max = new DateTime({ value, zone: behindZone });
818
+
819
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
820
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
821
+
822
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
823
+ when it's checked dateTime with zone ${aheadZone} is same or before the dateTime with zone ${behindZone}
824
+ then it should return true`,
825
+ () =>
826
+ {
827
+ assert.ok(min.isSameOrBefore(max));
828
+ }
829
+ );
830
+
831
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
832
+ when it's checked dateTime with zone ${behindZone} is same or before the dateTime with zone ${aheadZone}
833
+ then it should return false`,
834
+ () =>
835
+ {
836
+ assert.ok(!max.isSameOrBefore(min));
837
+ }
838
+ );
839
+ }
840
+
841
+ await testDifferentZones(compareDateTimeWithDifferentZones);
842
+
843
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
844
+ {
845
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
846
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
847
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
848
+
849
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
850
+ when it's checked one is same or before the other
851
+ then it should return true`,
852
+ () =>
853
+ {
854
+ assert.ok(dateTime1.isSameOrBefore(dateTime2));
855
+ assert.ok(dateTime2.isSameOrBefore(dateTime1));
856
+ }
857
+ );
858
+ }
859
+
860
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
861
+ });
862
+
863
+ await describe("DateTime Is After", async () =>
864
+ {
865
+ await test(`Given the same DateTime object
866
+ when it's checked one is after the other
867
+ then it should return false`,
868
+ () =>
869
+ {
870
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
871
+ assert.ok(!dateTime.isAfter(dateTime));
872
+ }
873
+ );
874
+
875
+ await test(`Given two DateTime object with same value and zone
876
+ when it's checked one is after the other
877
+ then it should return false`,
878
+ () =>
879
+ {
880
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
881
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
882
+
883
+ assert.ok(!dateTime1.isAfter(dateTime2));
884
+ assert.ok(!dateTime2.isAfter(dateTime1));
885
+ }
886
+ );
887
+
888
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
889
+ {
890
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
891
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
892
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
893
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
894
+ given(diff, "diff").ensureHasValue().ensureIsString();
895
+
896
+ const min = new DateTime({ value: minValue, zone: "utc" });
897
+ const max = new DateTime({ value: maxValue, zone: "utc" });
898
+
899
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
900
+ when it's checked dateTime with value ${minValue} is after the dateTime with value ${maxValue}
901
+ then it should return false`,
902
+ () =>
903
+ {
904
+ assert.ok(!min.isAfter(max));
905
+ }
906
+ );
907
+
908
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
909
+ when it's checked dateTime with value ${maxValue} is after the dateTime with value ${minValue}
910
+ then it should return true`,
911
+ () =>
912
+ {
913
+ assert.ok(max.isAfter(min));
914
+ }
915
+ );
916
+ }
917
+
918
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
919
+
920
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
921
+ {
922
+ given(value, "value").ensureHasValue().ensureIsString()
923
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
924
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
925
+ .ensure(t => DateTime.validateTimeZone(t));
926
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
927
+ .ensure(t => DateTime.validateTimeZone(t));
928
+ given(diff, "diff").ensureHasValue().ensureIsString();
929
+
930
+ const min = new DateTime({ value, zone: aheadZone });
931
+ const max = new DateTime({ value, zone: behindZone });
932
+
933
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
934
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
935
+
936
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
937
+ when it's checked dateTime with zone ${aheadZone} is after the dateTime with zone ${behindZone}
938
+ then it should return false`,
939
+ () =>
940
+ {
941
+ assert.ok(!min.isAfter(max));
942
+ }
943
+ );
944
+
945
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
946
+ when it's checked dateTime with zone ${behindZone} is after the dateTime with zone ${aheadZone}
947
+ then it should return true`,
948
+ () =>
949
+ {
950
+ assert.ok(max.isAfter(min));
951
+ }
952
+ );
953
+ }
954
+
955
+ await testDifferentZones(compareDateTimeWithDifferentZones);
956
+
957
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
958
+ {
959
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
960
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
961
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
962
+
963
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
964
+ when it's checked one is after the other
965
+ then it should return false`,
966
+ () =>
967
+ {
968
+ assert.ok(!dateTime1.isAfter(dateTime2));
969
+ assert.ok(!dateTime2.isAfter(dateTime1));
970
+ }
971
+ );
972
+ }
973
+
974
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
975
+ });
976
+
977
+ await describe("DateTime Is Same or After", async () =>
978
+ {
979
+ await test(`Given the same DateTime object
980
+ when it's checked one is same or after the other
981
+ then it should return true`,
982
+ () =>
983
+ {
984
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
985
+ assert.ok(dateTime.isSameOrAfter(dateTime));
986
+ }
987
+ );
988
+
989
+ await test(`Given two DateTime object with same value and zone
990
+ when it's checked one is same or after the other
991
+ then it should return true`,
992
+ () =>
993
+ {
994
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
995
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
996
+
997
+ assert.ok(dateTime1.isSameOrAfter(dateTime2));
998
+ assert.ok(dateTime2.isSameOrAfter(dateTime1));
999
+ }
1000
+ );
1001
+
1002
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string): Promise<void>
1003
+ {
1004
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
1005
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1006
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
1007
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1008
+ given(diff, "diff").ensureHasValue().ensureIsString();
1009
+
1010
+ const min = new DateTime({ value: minValue, zone: "utc" });
1011
+ const max = new DateTime({ value: maxValue, zone: "utc" });
1012
+
1013
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
1014
+ when it's checked dateTime with value ${minValue} is same or after the dateTime with value ${maxValue}
1015
+ then it should return false`,
1016
+ () =>
1017
+ {
1018
+ assert.ok(!min.isAfter(max));
1019
+ assert.ok(!min.isSameOrAfter(max));
1020
+ }
1021
+ );
1022
+
1023
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
1024
+ when it's checked dateTime with value ${maxValue} is same or after the dateTime with value ${minValue}
1025
+ then it should return true`,
1026
+ () =>
1027
+ {
1028
+ assert.ok(max.isSameOrAfter(min));
1029
+ }
1030
+ );
1031
+ }
1032
+
1033
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
1034
+
1035
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string): Promise<void>
1036
+ {
1037
+ given(value, "value").ensureHasValue().ensureIsString()
1038
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1039
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
1040
+ .ensure(t => DateTime.validateTimeZone(t));
1041
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
1042
+ .ensure(t => DateTime.validateTimeZone(t));
1043
+ given(diff, "diff").ensureHasValue().ensureIsString();
1044
+
1045
+ const min = new DateTime({ value, zone: aheadZone });
1046
+ const max = new DateTime({ value, zone: behindZone });
1047
+
1048
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
1049
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
1050
+
1051
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
1052
+ when it's checked dateTime with zone ${aheadZone} is same or after the dateTime with zone ${behindZone}
1053
+ then it should return false`,
1054
+ () =>
1055
+ {
1056
+ assert.ok(!min.isSameOrAfter(max));
1057
+ }
1058
+ );
1059
+
1060
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
1061
+ when it's checked dateTime with zone ${behindZone} is same or after the dateTime with zone ${aheadZone}
1062
+ then it should return true`,
1063
+ () =>
1064
+ {
1065
+ assert.ok(max.isSameOrAfter(min));
1066
+ }
1067
+ );
1068
+ }
1069
+
1070
+ await testDifferentZones(compareDateTimeWithDifferentZones);
1071
+
1072
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
1073
+ {
1074
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
1075
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
1076
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
1077
+
1078
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
1079
+ when it's checked one is same or after the other
1080
+ then it should return true`,
1081
+ () =>
1082
+ {
1083
+ assert.ok(dateTime1.isSameOrAfter(dateTime2));
1084
+ assert.ok(dateTime2.isSameOrAfter(dateTime1));
1085
+ }
1086
+ );
1087
+ }
1088
+
1089
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
1090
+ });
1091
+
1092
+ await describe("DateTime Time Difference", async () =>
1093
+ {
1094
+ await test(`Given the same DateTime object
1095
+ when checking the time difference between them
1096
+ then it should return Duration of 0 milliseconds`,
1097
+ () =>
1098
+ {
1099
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1100
+
1101
+ assert.strictEqual(dateTime.timeDiff(dateTime).toMilliSeconds(), 0);
1102
+ }
1103
+ );
1104
+
1105
+ await test(`Given two DateTime object with same value and zone
1106
+ when checking the time difference between them
1107
+ then it should return Duration of 0 milliseconds`,
1108
+ () =>
1109
+ {
1110
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1111
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1112
+
1113
+ assert.strictEqual(dateTime1.timeDiff(dateTime2).toMilliSeconds(), 0);
1114
+ assert.strictEqual(dateTime2.timeDiff(dateTime1).toMilliSeconds(), 0);
1115
+ }
1116
+ );
1117
+
1118
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string, timeDiff: Duration): Promise<void>
1119
+ {
1120
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
1121
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1122
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
1123
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1124
+ given(diff, "diff").ensureHasValue().ensureIsString();
1125
+ given(timeDiff, "timeDiff").ensureHasValue().ensureIsInstanceOf(Duration);
1126
+
1127
+ const min = new DateTime({ value: minValue, zone: "utc" });
1128
+ const max = new DateTime({ value: maxValue, zone: "utc" });
1129
+
1130
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
1131
+ when checking the time difference between them
1132
+ then it should return Duration of ${diff}`,
1133
+ () =>
1134
+ {
1135
+ assert.strictEqual(min.timeDiff(max).toMilliSeconds(), timeDiff.toMilliSeconds());
1136
+ assert.strictEqual(max.timeDiff(min).toMilliSeconds(), timeDiff.toMilliSeconds());
1137
+ }
1138
+ );
1139
+ }
1140
+
1141
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
1142
+
1143
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string, timeDiff: Duration): Promise<void>
1144
+ {
1145
+ given(value, "value").ensureHasValue().ensureIsString()
1146
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1147
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
1148
+ .ensure(t => DateTime.validateTimeZone(t));
1149
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
1150
+ .ensure(t => DateTime.validateTimeZone(t));
1151
+ given(diff, "diff").ensureHasValue().ensureIsString();
1152
+ given(timeDiff, "timeDiff").ensureHasValue().ensureIsInstanceOf(Duration);
1153
+
1154
+ const min = new DateTime({ value, zone: aheadZone });
1155
+ const max = new DateTime({ value, zone: behindZone });
1156
+
1157
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
1158
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
1159
+
1160
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
1161
+ when checking the time difference between them
1162
+ then it should return Duration of ${diff}`,
1163
+ () =>
1164
+ {
1165
+ assert.strictEqual(min.timeDiff(max).toMilliSeconds(), timeDiff.toMilliSeconds());
1166
+ assert.strictEqual(max.timeDiff(min).toMilliSeconds(), timeDiff.toMilliSeconds());
1167
+ }
1168
+ );
1169
+ }
1170
+
1171
+ await testDifferentZones(compareDateTimeWithDifferentZones);
1172
+
1173
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
1174
+ {
1175
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
1176
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
1177
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
1178
+
1179
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
1180
+ when checking the time difference between them
1181
+ then it should return Duration of 0 milliseconds`,
1182
+ () =>
1183
+ {
1184
+ assert.strictEqual(dateTime1.timeDiff(dateTime2).toMilliSeconds(), 0);
1185
+ assert.strictEqual(dateTime2.timeDiff(dateTime1).toMilliSeconds(), 0);
1186
+ }
1187
+ );
1188
+ }
1189
+
1190
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
1191
+ });
1192
+
1193
+ await describe("DateTime Days Difference", async () =>
1194
+ {
1195
+ await test(`Given the same DateTime object
1196
+ when checking the difference between them in calendar days
1197
+ then it should return 0`,
1198
+ () =>
1199
+ {
1200
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1201
+
1202
+ assert.strictEqual(dateTime.daysDiff(dateTime), 0);
1203
+ }
1204
+ );
1205
+
1206
+ await test(`Given two DateTime object with same value and zone
1207
+ when checking the difference between them in calendar days
1208
+ then it should return 0`,
1209
+ () =>
1210
+ {
1211
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1212
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1213
+
1214
+ assert.strictEqual(dateTime1.daysDiff(dateTime2), 0);
1215
+ assert.strictEqual(dateTime2.daysDiff(dateTime1), 0);
1216
+ }
1217
+ );
1218
+
1219
+ async function compareDateTimeWithDifferentValues(minValue: string, maxValue: string, diff: string,
1220
+ _: Duration, daysDiff: number): Promise<void>
1221
+ {
1222
+ given(minValue, "minValue").ensureHasValue().ensureIsString()
1223
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1224
+ given(maxValue, "maxValue").ensureHasValue().ensureIsString()
1225
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1226
+ given(diff, "diff").ensureHasValue().ensureIsString();
1227
+ given(daysDiff, "daysDiff").ensureHasValue().ensureIsNumber().ensure(t => t >= 0);
1228
+
1229
+ const min = new DateTime({ value: minValue, zone: "utc" });
1230
+ const max = new DateTime({ value: maxValue, zone: "utc" });
1231
+
1232
+ await test(`Given two DateTime objects ${minValue} and ${maxValue}, ${diff} apart in the same zone
1233
+ when checking the difference between them in calendar days
1234
+ then it should return ${daysDiff}`,
1235
+ () =>
1236
+ {
1237
+ assert.strictEqual(min.daysDiff(max), daysDiff);
1238
+ assert.strictEqual(max.daysDiff(min), daysDiff);
1239
+ }
1240
+ );
1241
+ }
1242
+
1243
+ await testDifferentSetOfValues(compareDateTimeWithDifferentValues);
1244
+
1245
+ async function compareDateTimeWithDifferentZones(value: string, behindZone: string, aheadZone: string, diff: string,
1246
+ _: Duration, daysDiff: number): Promise<void>
1247
+ {
1248
+ given(value, "value").ensureHasValue().ensureIsString()
1249
+ .ensure(t => DateTime.validateDateTimeFormat(t, DateTimeFormat_DEFAULT));
1250
+ given(behindZone, "behindZone").ensureHasValue().ensureIsString()
1251
+ .ensure(t => DateTime.validateTimeZone(t));
1252
+ given(aheadZone, "aheadZone").ensureHasValue().ensureIsString()
1253
+ .ensure(t => DateTime.validateTimeZone(t));
1254
+ given(diff, "diff").ensureHasValue().ensureIsString();
1255
+ given(daysDiff, "daysDiff").ensureHasValue().ensureIsNumber().ensure(t => t >= 0);
1256
+
1257
+ const min = new DateTime({ value, zone: aheadZone });
1258
+ const max = new DateTime({ value, zone: behindZone });
1259
+
1260
+ given(min, "min").ensure(t => t.timestamp < max.timestamp,
1261
+ `zone ${aheadZone} is not ahead of ${behindZone}`);
1262
+
1263
+ await test(`Given two DateTime object with same value and zones ${behindZone} and ${aheadZone} with difference ${diff}
1264
+ when checking the difference between them in calendar days
1265
+ then it should return ${daysDiff}`,
1266
+ () =>
1267
+ {
1268
+ assert.strictEqual(min.daysDiff(max), daysDiff);
1269
+ assert.strictEqual(max.daysDiff(min), daysDiff);
1270
+ }
1271
+ );
1272
+ }
1273
+
1274
+ await testDifferentZones(compareDateTimeWithDifferentZones);
1275
+
1276
+ async function compareDateTimeWithSameTimestamp(dateTime1: DateTime, dateTime2: DateTime): Promise<void>
1277
+ {
1278
+ given(dateTime1, "dateTime1").ensureHasValue().ensureIsType(DateTime);
1279
+ given(dateTime2, "dateTime2").ensureHasValue().ensureIsType(DateTime)
1280
+ .ensure(t => t.timestamp === dateTime1.timestamp, "Timestamps are different");
1281
+
1282
+ await test(`Given two DateTime object with different value and zones (${dateTime1.toString()} and ${dateTime2.toString()}) but represents same time
1283
+ when checking the difference between them in calendar days
1284
+ then it should return 0`,
1285
+ () =>
1286
+ {
1287
+ assert.strictEqual(dateTime1.daysDiff(dateTime2), 0);
1288
+ assert.strictEqual(dateTime2.daysDiff(dateTime1), 0);
1289
+ }
1290
+ );
1291
+ }
1292
+
1293
+ await testSameTimestampDifferentValueAndZone(compareDateTimeWithSameTimestamp);
1294
+ });
1295
+
1296
+ await describe("Compare three date time Is Between", async () =>
1297
+ {
1298
+ async function checkIsInvalidParams(dateTime: DateTime, start: DateTime, end: DateTime): Promise<void>
1299
+ {
1300
+ await test(`Given a DateTime (${dateTime.toString()}), and a start (${start.toString()}) and end (${end.toString()}) DateTime
1301
+ when start DateTime timeStamp is after end DateTime timeStamp
1302
+ then it should throw a validation error`,
1303
+ () =>
1304
+ {
1305
+ assert.throws(() => dateTime.isBetween(start, end), ArgumentException);
1306
+ }
1307
+ );
1308
+ }
1309
+
1310
+ async function checkIsCorrect(dateTime: DateTime, start: DateTime, end: DateTime): Promise<void>
1311
+ {
1312
+ given(dateTime, "dateTime").ensureHasValue().ensureIsType(DateTime);
1313
+ given(start, "start").ensureHasValue().ensureIsType(DateTime);
1314
+ given(end, "end").ensureHasValue().ensureIsType(DateTime)
1315
+ .ensure(t => t.isSameOrAfter(start), "must be same or after start");
1316
+
1317
+ await test(`Given a DateTime (${dateTime.toString()}), and a start (${start.toString()}) and end (${end.toString()}) DateTime
1318
+ when dateTime is in between start and end
1319
+ then it should return true`,
1320
+ () =>
1321
+ {
1322
+ assert.ok(dateTime.isBetween(start, end));
1323
+ }
1324
+ );
1325
+ }
1326
+
1327
+ async function checkIsFalse(dateTime: DateTime, start: DateTime, end: DateTime): Promise<void>
1328
+ {
1329
+ given(dateTime, "dateTime").ensureHasValue().ensureIsType(DateTime);
1330
+ given(start, "start").ensureHasValue().ensureIsType(DateTime);
1331
+ given(end, "end").ensureHasValue().ensureIsType(DateTime)
1332
+ .ensure(t => t.isSameOrAfter(start), "must be same or after start");
1333
+
1334
+ await test(`Given a DateTime (${dateTime.toString()}), and a start (${start.toString()}) and end (${end.toString()}) DateTime
1335
+ when dateTime is not in between start and end
1336
+ then it should return false`,
1337
+ () =>
1338
+ {
1339
+ assert.ok(!dateTime.isBetween(start, end));
1340
+ }
1341
+ );
1342
+ }
1343
+
1344
+ await test(`Given dateTime start and end as the same DateTime object
1345
+ when it's checked it's between the same DateTime
1346
+ then it should return true`, () =>
1347
+ {
1348
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1349
+
1350
+ assert.ok(dateTime.isBetween(dateTime, dateTime));
1351
+ });
1352
+
1353
+ await test(`Given dateTime start and end with same value and zone
1354
+ when it's compared isBetween
1355
+ then it should return true`, () =>
1356
+ {
1357
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1358
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1359
+ const dateTime3 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1360
+
1361
+ assert.ok(dateTime1.isBetween(dateTime2, dateTime3));
1362
+ assert.ok(dateTime2.isBetween(dateTime1, dateTime3));
1363
+ assert.ok(dateTime3.isBetween(dateTime1, dateTime2));
1364
+ });
1365
+
1366
+ await describe("Compare different minutes", async () =>
1367
+ {
1368
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1369
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:01:00", zone: "utc" });
1370
+ const dateTime3 = new DateTime({ value: "2024-01-01 10:02:00", zone: "utc" });
1371
+
1372
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1373
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1374
+
1375
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1376
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1377
+
1378
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1379
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1380
+ });
1381
+
1382
+ await describe("Compare different hours", async () =>
1383
+ {
1384
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1385
+ const dateTime2 = new DateTime({ value: "2024-01-01 11:00:00", zone: "utc" });
1386
+ const dateTime3 = new DateTime({ value: "2024-01-01 12:00:00", zone: "utc" });
1387
+
1388
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1389
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1390
+
1391
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1392
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1393
+
1394
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1395
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1396
+ });
1397
+
1398
+ await describe("Compare different days", async () =>
1399
+ {
1400
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1401
+ const dateTime2 = new DateTime({ value: "2024-01-02 10:00:00", zone: "utc" });
1402
+ const dateTime3 = new DateTime({ value: "2024-01-03 10:00:00", zone: "utc" });
1403
+
1404
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1405
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1406
+
1407
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1408
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1409
+
1410
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1411
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1412
+ });
1413
+
1414
+ await describe("Compare different months", async () =>
1415
+ {
1416
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1417
+ const dateTime2 = new DateTime({ value: "2024-02-01 10:00:00", zone: "utc" });
1418
+ const dateTime3 = new DateTime({ value: "2024-03-01 10:00:00", zone: "utc" });
1419
+
1420
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1421
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1422
+
1423
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1424
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1425
+
1426
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1427
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1428
+ });
1429
+
1430
+ await describe("Compare different years", async () =>
1431
+ {
1432
+ const dateTime1 = new DateTime({ value: "2023-01-01 10:00:00", zone: "utc" });
1433
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1434
+ const dateTime3 = new DateTime({ value: "2025-01-01 10:00:00", zone: "utc" });
1435
+
1436
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1437
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1438
+
1439
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1440
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1441
+
1442
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1443
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1444
+ });
1445
+
1446
+ await describe("Compare different zones", async () =>
1447
+ {
1448
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "UTC+5:30" });
1449
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1450
+ const dateTime3 = new DateTime({ value: "2024-01-01 10:00:00", zone: "America/Los_Angeles" });
1451
+
1452
+ await checkIsFalse(dateTime1, dateTime2, dateTime3);
1453
+ await checkIsInvalidParams(dateTime1, dateTime3, dateTime2);
1454
+
1455
+ await checkIsCorrect(dateTime2, dateTime1, dateTime3);
1456
+ await checkIsInvalidParams(dateTime2, dateTime3, dateTime1);
1457
+
1458
+ await checkIsFalse(dateTime3, dateTime1, dateTime2);
1459
+ await checkIsInvalidParams(dateTime3, dateTime2, dateTime1);
1460
+ });
1461
+ });
1462
+
1463
+ await describe("Compare DateTime is within time range", async () =>
1464
+ {
1465
+ async function checkIsInvalidParams(dateTime: DateTime, startTimeCode: string, endTimeCode: string, reason: string): Promise<void>
1466
+ {
1467
+ await test(`Given a DateTime (${dateTime.toString()}), and a startTimeCode (${startTimeCode}) and endTimeCode (${endTimeCode})
1468
+ when ${reason}
1469
+ then it should throw a validation error`,
1470
+ () =>
1471
+ {
1472
+ assert.throws(() => dateTime.isWithinTimeRange(startTimeCode, endTimeCode), ArgumentException);
1473
+ }
1474
+ );
1475
+ }
1476
+
1477
+ async function checkIsCorrect(dateTime: DateTime, startTimeCode: string, endTimeCode: string): Promise<void>
1478
+ {
1479
+ given(dateTime, "dateTime").ensureHasValue().ensureIsType(DateTime);
1480
+ given(startTimeCode, "startTimeCode").ensureHasValue().ensureIsString();
1481
+ given(endTimeCode, "startTimeCode").ensureHasValue().ensureIsString();
1482
+
1483
+ await test(`Given a DateTime (${dateTime.toString()}), and a startTimeCode (${startTimeCode}) and endTimeCode (${endTimeCode})
1484
+ when dateTime is within start and end time
1485
+ then it should return true`,
1486
+ () =>
1487
+ {
1488
+ assert.ok(dateTime.isWithinTimeRange(startTimeCode, endTimeCode));
1489
+ }
1490
+ );
1491
+ }
1492
+
1493
+ async function checkIsFalse(dateTime: DateTime, startTimeCode: string, endTimeCode: string): Promise<void>
1494
+ {
1495
+ given(dateTime, "dateTime").ensureHasValue().ensureIsType(DateTime);
1496
+ given(startTimeCode, "startTimeCode").ensureHasValue().ensureIsString();
1497
+ given(endTimeCode, "startTimeCode").ensureHasValue().ensureIsString();
1498
+
1499
+ await test(`Given a DateTime (${dateTime.toString()}), and a startTimeCode (${startTimeCode}) and endTimeCode (${endTimeCode})
1500
+ when dateTime is not within start and end time
1501
+ then it should return false`,
1502
+ () =>
1503
+ {
1504
+ assert.ok(!dateTime.isWithinTimeRange(startTimeCode, endTimeCode));
1505
+ }
1506
+ );
1507
+ }
1508
+
1509
+ await test(`Given a DateTime, start and end time same as that dateTime
1510
+ when dateTime is checked to be within start and end time
1511
+ then it should return true`,
1512
+ () =>
1513
+ {
1514
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1515
+
1516
+ assert.ok(dateTime.isWithinTimeRange(dateTime.timeCode, dateTime.timeCode));
1517
+ });
1518
+
1519
+ await describe("Compare to Invalid start time code", async () =>
1520
+ {
1521
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1522
+
1523
+ await checkIsInvalidParams(dateTime, "", "1000", "start time code is invalid");
1524
+ await checkIsInvalidParams(dateTime, "11", "1000", "start time code is invalid");
1525
+ await checkIsInvalidParams(dateTime, "10:00", "1000", "start time code is invalid");
1526
+ await checkIsInvalidParams(dateTime, "2400", "1000", "start time code is invalid");
1527
+ await checkIsInvalidParams(dateTime, "10000", "1000", "start time code is invalid");
1528
+ });
1529
+
1530
+ await describe("Compare to Invalid end time code", async () =>
1531
+ {
1532
+ const dateTime = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1533
+
1534
+ await checkIsInvalidParams(dateTime, "1000", "", "end time code is invalid");
1535
+ await checkIsInvalidParams(dateTime, "1000", "11", "end time code is invalid");
1536
+ await checkIsInvalidParams(dateTime, "1000", "10:00", "end time code is invalid");
1537
+ await checkIsInvalidParams(dateTime, "1000", "2400", "end time code is invalid");
1538
+ await checkIsInvalidParams(dateTime, "1000", "10000", "end time code is invalid");
1539
+ });
1540
+
1541
+ await describe("Compare different minutes", async () =>
1542
+ {
1543
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1544
+ const dateTime2 = new DateTime({ value: "2024-01-01 10:01:00", zone: "utc" });
1545
+ const dateTime3 = new DateTime({ value: "2024-01-01 10:02:00", zone: "utc" });
1546
+
1547
+ await checkIsFalse(dateTime1, dateTime2.timeCode, dateTime3.timeCode);
1548
+ await checkIsInvalidParams(dateTime1, dateTime3.timeCode, dateTime2.timeCode,
1549
+ "start time is greater than end time");
1550
+
1551
+ await checkIsCorrect(dateTime2, dateTime1.timeCode, dateTime3.timeCode);
1552
+ await checkIsInvalidParams(dateTime2, dateTime3.timeCode, dateTime1.timeCode,
1553
+ "start time is greater than end time");
1554
+
1555
+ await checkIsFalse(dateTime3, dateTime1.timeCode, dateTime2.timeCode);
1556
+ await checkIsInvalidParams(dateTime3, dateTime2.timeCode, dateTime1.timeCode,
1557
+ "start time is greater than end time");
1558
+ });
1559
+
1560
+ await describe("Compare different hours", async () =>
1561
+ {
1562
+ const dateTime1 = new DateTime({ value: "2024-01-01 10:00:00", zone: "utc" });
1563
+ const dateTime2 = new DateTime({ value: "2024-01-01 11:00:00", zone: "utc" });
1564
+ const dateTime3 = new DateTime({ value: "2024-01-01 12:00:00", zone: "utc" });
1565
+
1566
+ await checkIsFalse(dateTime1, dateTime2.timeCode, dateTime3.timeCode);
1567
+ await checkIsInvalidParams(dateTime1, dateTime3.timeCode, dateTime2.timeCode,
1568
+ "start time is greater than end time");
1569
+
1570
+ await checkIsCorrect(dateTime2, dateTime1.timeCode, dateTime3.timeCode);
1571
+ await checkIsInvalidParams(dateTime2, dateTime3.timeCode, dateTime1.timeCode,
1572
+ "start time is greater than end time");
1573
+
1574
+ await checkIsFalse(dateTime3, dateTime1.timeCode, dateTime2.timeCode);
1575
+ await checkIsInvalidParams(dateTime3, dateTime2.timeCode, dateTime1.timeCode,
1576
+ "start time is greater than end time");
1577
+ });
1578
+ });
1579
+ });