@fable-org/fable-library-ts 2.0.0-beta.3 → 2.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Array.ts +1385 -1378
- package/Async.ts +13 -12
- package/AsyncBuilder.ts +10 -11
- package/BigInt.ts +6 -6
- package/BitConverter.ts +3 -3
- package/Boolean.ts +3 -2
- package/CHANGELOG.md +12 -0
- package/Char.ts +38 -35
- package/Choice.ts +326 -301
- package/CollectionUtil.ts +4 -4
- package/Date.ts +67 -62
- package/DateOffset.ts +48 -57
- package/DateOnly.ts +8 -8
- package/Decimal.ts +9 -9
- package/Double.ts +3 -2
- package/Encoding.ts +1 -1
- package/Event.ts +3 -3
- package/FSharp.Collections.ts +53 -34
- package/FSharp.Core.CompilerServices.ts +38 -37
- package/FSharp.Core.ts +186 -185
- package/Global.ts +80 -37
- package/Guid.ts +7 -6
- package/Int32.ts +20 -17
- package/List.ts +1429 -1417
- package/Long.ts +6 -5
- package/MailboxProcessor.ts +8 -7
- package/Map.ts +1550 -1552
- package/MapUtil.ts +5 -5
- package/MutableMap.ts +358 -345
- package/MutableSet.ts +250 -249
- package/Native.ts +19 -11
- package/Numeric.ts +1 -1
- package/Observable.ts +3 -3
- package/Option.ts +10 -4
- package/Random.ts +196 -194
- package/Range.ts +57 -56
- package/Reflection.ts +73 -40
- package/RegExp.ts +5 -3
- package/Result.ts +201 -196
- package/Seq.ts +1517 -1525
- package/Seq2.ts +130 -129
- package/Set.ts +1955 -1955
- package/String.ts +41 -38
- package/System.Collections.Generic.ts +401 -380
- package/System.Text.ts +204 -203
- package/System.ts +366 -0
- package/TimeOnly.ts +10 -10
- package/TimeSpan.ts +11 -11
- package/Timer.ts +2 -2
- package/Types.ts +1 -19
- package/Uri.ts +13 -10
- package/Util.ts +77 -21
- package/package.json +22 -22
- package/tsconfig.json +18 -5
- package/SystemException.ts +0 -7
package/CollectionUtil.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { equals, isArrayLike } from "./Util.
|
|
1
|
+
import { Exception, MutableArray, equals, isArrayLike } from "./Util.ts";
|
|
2
2
|
|
|
3
3
|
export function count<T>(col: Iterable<T>): number {
|
|
4
4
|
if (typeof (col as any)["System.Collections.Generic.ICollection`1.get_Count"] === "function") {
|
|
@@ -29,7 +29,7 @@ export function isReadOnly<T>(col: Iterable<T>): boolean {
|
|
|
29
29
|
return (col as any)["System.Collections.Generic.ICollection`1.get_IsReadOnly"](); // collection
|
|
30
30
|
} else {
|
|
31
31
|
if (isArrayLike(col)) {
|
|
32
|
-
return
|
|
32
|
+
return false; // array, resize array
|
|
33
33
|
} else {
|
|
34
34
|
if (typeof (col as any).size === "number") {
|
|
35
35
|
return false; // map, set
|
|
@@ -41,7 +41,7 @@ export function isReadOnly<T>(col: Iterable<T>): boolean {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export function copyTo<T>(col: Iterable<T>, array: T
|
|
44
|
+
export function copyTo<T>(col: Iterable<T>, array: MutableArray<T>, arrayIndex: number) {
|
|
45
45
|
if (typeof (col as any)["System.Collections.Generic.ICollection`1.CopyToZ3B4C077E"] === "function") {
|
|
46
46
|
(col as any)["System.Collections.Generic.ICollection`1.CopyToZ3B4C077E"](array, arrayIndex); // collection
|
|
47
47
|
} else {
|
|
@@ -94,7 +94,7 @@ export function add<T>(col: Iterable<T>, item: T): void {
|
|
|
94
94
|
if ((col as any).has(item[0]) === false) {
|
|
95
95
|
(col as any).set(item[0], item[1]); // map
|
|
96
96
|
} else {
|
|
97
|
-
throw new
|
|
97
|
+
throw new Exception("An item with the same key has already been added. Key: " + item[0]);
|
|
98
98
|
}
|
|
99
99
|
} else {
|
|
100
100
|
// TODO: throw for other collections?
|
package/Date.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* Basically; invariant: date.getTime() always return UTC time.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { int64, toInt64, toFloat64 } from "./BigInt.
|
|
12
|
-
import { FSharpRef } from "./Types.
|
|
13
|
-
import { compareDates,
|
|
11
|
+
import { int64, toInt64, toFloat64 } from "./BigInt.ts";
|
|
12
|
+
import { FSharpRef } from "./Types.ts";
|
|
13
|
+
import { Exception, compareDates, DateTimeKind, dateOffset, IDateTime, IDateTimeOffset, padWithZeros } from "./Util.ts";
|
|
14
14
|
|
|
15
15
|
export type OffsetInMinutes = number;
|
|
16
16
|
export type Offset = "Z" | OffsetInMinutes | null;
|
|
@@ -75,7 +75,7 @@ function parseQuotedString(format: string, pos: number): [string, number] {
|
|
|
75
75
|
result += format[pos];
|
|
76
76
|
} else {
|
|
77
77
|
// This means that '\' is the last character in the string.
|
|
78
|
-
throw new
|
|
78
|
+
throw new Exception("Invalid string format");
|
|
79
79
|
}
|
|
80
80
|
} else {
|
|
81
81
|
result += currentChar;
|
|
@@ -84,7 +84,7 @@ function parseQuotedString(format: string, pos: number): [string, number] {
|
|
|
84
84
|
|
|
85
85
|
if (!foundQuote) {
|
|
86
86
|
// We could not find the matching quote
|
|
87
|
-
throw new
|
|
87
|
+
throw new Exception(`Invalid string format could not find matching quote for ${quoteChar}`);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return [result, pos - beginPos + 1];
|
|
@@ -94,7 +94,7 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
94
94
|
let cursorPos = 0;
|
|
95
95
|
let tokenLength = 0;
|
|
96
96
|
let result = "";
|
|
97
|
-
const localizedDate = utc ? DateTime(date.getTime(),
|
|
97
|
+
const localizedDate = utc ? DateTime(date.getTime(), DateTimeKind.Utc) : date;
|
|
98
98
|
|
|
99
99
|
while (cursorPos < format.length) {
|
|
100
100
|
const token = format[cursorPos];
|
|
@@ -195,14 +195,14 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
195
195
|
cursorPos += tokenLength;
|
|
196
196
|
switch (tokenLength) {
|
|
197
197
|
case 1:
|
|
198
|
-
switch (
|
|
199
|
-
case
|
|
198
|
+
switch (getKind(localizedDate)) {
|
|
199
|
+
case DateTimeKind.Utc:
|
|
200
200
|
result += "Z";
|
|
201
201
|
break;
|
|
202
|
-
case
|
|
203
|
-
result += dateOffsetToString(localizedDate.getTimezoneOffset() * -
|
|
202
|
+
case DateTimeKind.Local:
|
|
203
|
+
result += dateOffsetToString(localizedDate.getTimezoneOffset() * -60_000);
|
|
204
204
|
break;
|
|
205
|
-
case
|
|
205
|
+
case DateTimeKind.Unspecified:
|
|
206
206
|
break;
|
|
207
207
|
}
|
|
208
208
|
break;
|
|
@@ -288,15 +288,15 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
288
288
|
cursorPos += tokenLength;
|
|
289
289
|
let utcOffsetText = "";
|
|
290
290
|
|
|
291
|
-
switch (
|
|
292
|
-
case
|
|
291
|
+
switch (getKind(localizedDate)) {
|
|
292
|
+
case DateTimeKind.Utc:
|
|
293
293
|
utcOffsetText = "+00:00";
|
|
294
294
|
break;
|
|
295
|
-
case
|
|
296
|
-
utcOffsetText = dateOffsetToString(localizedDate.getTimezoneOffset() * -
|
|
295
|
+
case DateTimeKind.Local:
|
|
296
|
+
utcOffsetText = dateOffsetToString(localizedDate.getTimezoneOffset() * -60_000);
|
|
297
297
|
break;
|
|
298
|
-
case
|
|
299
|
-
utcOffsetText = dateOffsetToString(toLocalTime(localizedDate).getTimezoneOffset() * -
|
|
298
|
+
case DateTimeKind.Unspecified:
|
|
299
|
+
utcOffsetText = dateOffsetToString(toLocalTime(localizedDate).getTimezoneOffset() * -60_000);
|
|
300
300
|
break;
|
|
301
301
|
}
|
|
302
302
|
|
|
@@ -336,7 +336,7 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
336
336
|
cursorPos += 2;
|
|
337
337
|
result += dateToStringWithCustomFormat(localizedDate, String.fromCharCode(nextChar), utc);
|
|
338
338
|
} else {
|
|
339
|
-
throw new
|
|
339
|
+
throw new Exception("Invalid format string");
|
|
340
340
|
}
|
|
341
341
|
break;
|
|
342
342
|
case "\\":
|
|
@@ -345,7 +345,7 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
345
345
|
cursorPos += 2;
|
|
346
346
|
result += String.fromCharCode(nextChar2);
|
|
347
347
|
} else {
|
|
348
|
-
throw new
|
|
348
|
+
throw new Exception("Invalid format string");
|
|
349
349
|
}
|
|
350
350
|
break;
|
|
351
351
|
default:
|
|
@@ -358,8 +358,8 @@ function dateToStringWithCustomFormat(date: Date, format: string, utc: boolean)
|
|
|
358
358
|
return result;
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
export function
|
|
362
|
-
return value.kind
|
|
361
|
+
export function getKind(value: IDateTime): DateTimeKind {
|
|
362
|
+
return value.kind ?? DateTimeKind.Unspecified;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
365
|
export function unixEpochMillisecondsToTicks(ms: number, offset: number): int64 {
|
|
@@ -374,7 +374,7 @@ export function dateOffsetToString(offset: number) {
|
|
|
374
374
|
const isMinus = offset < 0;
|
|
375
375
|
offset = Math.abs(offset);
|
|
376
376
|
const hours = ~~(offset / 3600000);
|
|
377
|
-
const minutes = (offset % 3600000) /
|
|
377
|
+
const minutes = (offset % 3600000) / 60_000;
|
|
378
378
|
return (isMinus ? "-" : "+") +
|
|
379
379
|
padWithZeros(hours, 2) + ":" +
|
|
380
380
|
padWithZeros(minutes, 2);
|
|
@@ -385,7 +385,7 @@ function dateToISOString(d: IDateTime, utc: boolean) {
|
|
|
385
385
|
return d.toISOString();
|
|
386
386
|
} else {
|
|
387
387
|
// JS Date is always local
|
|
388
|
-
const printOffset = d.kind == null ? true : d.kind ===
|
|
388
|
+
const printOffset = d.kind == null ? true : d.kind === DateTimeKind.Local;
|
|
389
389
|
return padWithZeros(d.getFullYear(), 4) + "-" +
|
|
390
390
|
padWithZeros(d.getMonth() + 1, 2) + "-" +
|
|
391
391
|
padWithZeros(d.getDate(), 2) + "T" +
|
|
@@ -393,7 +393,7 @@ function dateToISOString(d: IDateTime, utc: boolean) {
|
|
|
393
393
|
padWithZeros(d.getMinutes(), 2) + ":" +
|
|
394
394
|
padWithZeros(d.getSeconds(), 2) + "." +
|
|
395
395
|
padWithZeros(d.getMilliseconds(), 3) +
|
|
396
|
-
(printOffset ? dateOffsetToString(d.getTimezoneOffset() * -
|
|
396
|
+
(printOffset ? dateOffsetToString(d.getTimezoneOffset() * -60_000) : "");
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
|
|
@@ -413,7 +413,7 @@ function dateToStringWithOffset(date: IDateTimeOffset, format?: string) {
|
|
|
413
413
|
case "T": return dateToString_T(toUniversalTime(d));
|
|
414
414
|
case "t": return dateToString_t(toUniversalTime(d));
|
|
415
415
|
case "O": case "o": return dateToISOStringWithOffset(d, (date.offset ?? 0));
|
|
416
|
-
default: throw new
|
|
416
|
+
default: throw new Exception("Unrecognized Date print format");
|
|
417
417
|
}
|
|
418
418
|
} else {
|
|
419
419
|
return dateToStringWithCustomFormat(d, format, true);
|
|
@@ -445,7 +445,7 @@ function dateToString_t(date: IDateTime) {
|
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
function dateToStringWithKind(date: IDateTime, format?: string) {
|
|
448
|
-
const utc = date.kind ===
|
|
448
|
+
const utc = date.kind === DateTimeKind.Utc;
|
|
449
449
|
if (typeof format !== "string") {
|
|
450
450
|
return utc ? date.toUTCString() : date.toLocaleString();
|
|
451
451
|
} else if (format.length === 1) {
|
|
@@ -457,7 +457,7 @@ function dateToStringWithKind(date: IDateTime, format?: string) {
|
|
|
457
457
|
case "O": case "o":
|
|
458
458
|
return dateToISOString(date, utc);
|
|
459
459
|
default:
|
|
460
|
-
throw new
|
|
460
|
+
throw new Exception("Unrecognized Date print format");
|
|
461
461
|
}
|
|
462
462
|
} else {
|
|
463
463
|
return dateToStringWithCustomFormat(date, format, utc);
|
|
@@ -470,30 +470,35 @@ export function toString(date: IDateTime | IDateTimeOffset, format?: string, _pr
|
|
|
470
470
|
: dateToStringWithKind(date, format);
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
-
export function DateTime(value: number, kind?:
|
|
473
|
+
export function DateTime(value: number, kind?: DateTimeKind) {
|
|
474
474
|
const d = new Date(value) as IDateTime;
|
|
475
|
-
d.kind = (kind == null ?
|
|
475
|
+
d.kind = (kind == null ? DateTimeKind.Unspecified : kind);
|
|
476
476
|
return d;
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
-
export function fromTicks(ticks: number | bigint, kind?:
|
|
480
|
-
kind = kind != null ? kind :
|
|
479
|
+
export function fromTicks(ticks: number | bigint, kind?: DateTimeKind) {
|
|
480
|
+
kind = kind != null ? kind : DateTimeKind.Local; // better default than Unspecified
|
|
481
481
|
let date = DateTime(ticksToUnixEpochMilliseconds(ticks), kind);
|
|
482
482
|
|
|
483
483
|
// Ticks are local to offset (in this case, either UTC or Local/Unknown).
|
|
484
484
|
// If kind is anything but UTC, that means that the tick number was not
|
|
485
485
|
// in utc, thus getTime() cannot return UTC, and needs to be shifted.
|
|
486
|
-
if (kind !==
|
|
486
|
+
if (kind !== DateTimeKind.Utc) {
|
|
487
487
|
date = DateTime(date.getTime() - dateOffset(date), kind);
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
return date;
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
-
export function
|
|
493
|
+
export function fromDateTime(dateOnly: IDateTime, timeOnly: number, kind?: DateTimeKind) {
|
|
494
|
+
const d = DateTime(dateOnly.getTime() + timeOnly, kind);
|
|
495
|
+
return DateTime(d.getTime() - dateOffset(d), kind);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export function fromDateTimeOffset(date: IDateTimeOffset, kind: DateTimeKind) {
|
|
494
499
|
switch (kind) {
|
|
495
|
-
case
|
|
496
|
-
case
|
|
500
|
+
case DateTimeKind.Utc: return DateTime(date.getTime(), DateTimeKind.Utc);
|
|
501
|
+
case DateTimeKind.Local: return DateTime(date.getTime(), DateTimeKind.Local);
|
|
497
502
|
default:
|
|
498
503
|
const d = DateTime(date.getTime() + (date.offset ?? 0), kind);
|
|
499
504
|
return DateTime(d.getTime() - dateOffset(d), kind);
|
|
@@ -506,17 +511,17 @@ export function getTicks(date: IDateTime | IDateTimeOffset) {
|
|
|
506
511
|
|
|
507
512
|
export function minValue() {
|
|
508
513
|
// This is "0001-01-01T00:00:00.000Z", actual JS min value is -8640000000000000
|
|
509
|
-
return DateTime(-62135596800000,
|
|
514
|
+
return DateTime(-62135596800000, DateTimeKind.Utc);
|
|
510
515
|
}
|
|
511
516
|
|
|
512
517
|
export function maxValue() {
|
|
513
518
|
// This is "9999-12-31T23:59:59.999Z", actual JS max value is 8640000000000000
|
|
514
|
-
return DateTime(253402300799999,
|
|
519
|
+
return DateTime(253402300799999, DateTimeKind.Utc);
|
|
515
520
|
}
|
|
516
521
|
|
|
517
522
|
export function parseRaw(input: string): [Date, Offset] {
|
|
518
523
|
function fail() {
|
|
519
|
-
throw new
|
|
524
|
+
throw new Exception(`The string is not a valid Date: ${input}`);
|
|
520
525
|
}
|
|
521
526
|
|
|
522
527
|
if (input == null || input.trim() === "") {
|
|
@@ -574,7 +579,7 @@ export function parseRaw(input: string): [Date, Offset] {
|
|
|
574
579
|
}
|
|
575
580
|
date = new Date(baseDate.getTime() + timeInSeconds * 1000);
|
|
576
581
|
// correct for daylight savings time
|
|
577
|
-
date = new Date(date.getTime() + (date.getTimezoneOffset() - baseDate.getTimezoneOffset()) *
|
|
582
|
+
date = new Date(date.getTime() + (date.getTimezoneOffset() - baseDate.getTimezoneOffset()) * 60_000);
|
|
578
583
|
} else {
|
|
579
584
|
fail();
|
|
580
585
|
}
|
|
@@ -593,8 +598,8 @@ export function parse(str: string, detectUTC = false): IDateTime {
|
|
|
593
598
|
// .NET always parses DateTime as Local if there's offset info (even "Z")
|
|
594
599
|
// Newtonsoft.Json uses UTC if the offset is "Z"
|
|
595
600
|
const kind = offset != null
|
|
596
|
-
? (detectUTC && offset === "Z" ?
|
|
597
|
-
:
|
|
601
|
+
? (detectUTC && offset === "Z" ? DateTimeKind.Utc : DateTimeKind.Local)
|
|
602
|
+
: DateTimeKind.Unspecified;
|
|
598
603
|
return DateTime(date.getTime(), kind);
|
|
599
604
|
}
|
|
600
605
|
|
|
@@ -610,12 +615,12 @@ export function tryParse(v: string, defValue: FSharpRef<IDateTime>): boolean {
|
|
|
610
615
|
export function create(
|
|
611
616
|
year: number, month: number, day: number,
|
|
612
617
|
h: number = 0, m: number = 0, s: number = 0,
|
|
613
|
-
ms: number = 0, kind?:
|
|
614
|
-
const date = kind ===
|
|
618
|
+
ms: number = 0, kind?: DateTimeKind) {
|
|
619
|
+
const date = kind === DateTimeKind.Utc
|
|
615
620
|
? new Date(Date.UTC(year, month - 1, day, h, m, s, ms))
|
|
616
621
|
: new Date(year, month - 1, day, h, m, s, ms);
|
|
617
622
|
if (year <= 99) {
|
|
618
|
-
if (kind ===
|
|
623
|
+
if (kind === DateTimeKind.Utc) {
|
|
619
624
|
date.setUTCFullYear(year, month - 1, day);
|
|
620
625
|
} else {
|
|
621
626
|
date.setFullYear(year, month - 1, day);
|
|
@@ -623,17 +628,17 @@ export function create(
|
|
|
623
628
|
}
|
|
624
629
|
const dateValue = date.getTime();
|
|
625
630
|
if (isNaN(dateValue)) {
|
|
626
|
-
throw new
|
|
631
|
+
throw new Exception("The parameters describe an unrepresentable Date.");
|
|
627
632
|
}
|
|
628
633
|
return DateTime(dateValue, kind);
|
|
629
634
|
}
|
|
630
635
|
|
|
631
636
|
export function now() {
|
|
632
|
-
return DateTime(Date.now(),
|
|
637
|
+
return DateTime(Date.now(), DateTimeKind.Local);
|
|
633
638
|
}
|
|
634
639
|
|
|
635
640
|
export function utcNow() {
|
|
636
|
-
return DateTime(Date.now(),
|
|
641
|
+
return DateTime(Date.now(), DateTimeKind.Utc);
|
|
637
642
|
}
|
|
638
643
|
|
|
639
644
|
export function today() {
|
|
@@ -651,20 +656,20 @@ export function daysInMonth(year: number, month: number) {
|
|
|
651
656
|
}
|
|
652
657
|
|
|
653
658
|
export function toUniversalTime(date: IDateTime) {
|
|
654
|
-
return date.kind ===
|
|
659
|
+
return date.kind === DateTimeKind.Utc ? date : DateTime(date.getTime(), DateTimeKind.Utc);
|
|
655
660
|
}
|
|
656
661
|
|
|
657
662
|
export function toLocalTime(date: IDateTime) {
|
|
658
|
-
return date.kind ===
|
|
663
|
+
return date.kind === DateTimeKind.Local ? date : DateTime(date.getTime(), DateTimeKind.Local);
|
|
659
664
|
}
|
|
660
665
|
|
|
661
|
-
export function specifyKind(d: IDateTime, kind:
|
|
666
|
+
export function specifyKind(d: IDateTime, kind: DateTimeKind) {
|
|
662
667
|
return create(year(d), month(d), day(d), hour(d), minute(d), second(d), millisecond(d), kind);
|
|
663
668
|
}
|
|
664
669
|
|
|
665
670
|
export function timeOfDay(d: IDateTime) {
|
|
666
671
|
return hour(d) * 3600000
|
|
667
|
-
+ minute(d) *
|
|
672
|
+
+ minute(d) * 60_000
|
|
668
673
|
+ second(d) * 1000
|
|
669
674
|
+ millisecond(d);
|
|
670
675
|
}
|
|
@@ -674,35 +679,35 @@ export function date(d: IDateTime) {
|
|
|
674
679
|
}
|
|
675
680
|
|
|
676
681
|
export function day(d: IDateTime) {
|
|
677
|
-
return d.kind ===
|
|
682
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCDate() : d.getDate();
|
|
678
683
|
}
|
|
679
684
|
|
|
680
685
|
export function hour(d: IDateTime) {
|
|
681
|
-
return d.kind ===
|
|
686
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCHours() : d.getHours();
|
|
682
687
|
}
|
|
683
688
|
|
|
684
689
|
export function millisecond(d: IDateTime) {
|
|
685
|
-
return d.kind ===
|
|
690
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCMilliseconds() : d.getMilliseconds();
|
|
686
691
|
}
|
|
687
692
|
|
|
688
693
|
export function minute(d: IDateTime) {
|
|
689
|
-
return d.kind ===
|
|
694
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCMinutes() : d.getMinutes();
|
|
690
695
|
}
|
|
691
696
|
|
|
692
697
|
export function month(d: IDateTime) {
|
|
693
|
-
return (d.kind ===
|
|
698
|
+
return (d.kind === DateTimeKind.Utc ? d.getUTCMonth() : d.getMonth()) + 1;
|
|
694
699
|
}
|
|
695
700
|
|
|
696
701
|
export function second(d: IDateTime) {
|
|
697
|
-
return d.kind ===
|
|
702
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCSeconds() : d.getSeconds();
|
|
698
703
|
}
|
|
699
704
|
|
|
700
705
|
export function year(d: IDateTime) {
|
|
701
|
-
return d.kind ===
|
|
706
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCFullYear() : d.getFullYear();
|
|
702
707
|
}
|
|
703
708
|
|
|
704
709
|
export function dayOfWeek(d: IDateTime) {
|
|
705
|
-
return d.kind ===
|
|
710
|
+
return d.kind === DateTimeKind.Utc ? d.getUTCDay() : d.getDay();
|
|
706
711
|
}
|
|
707
712
|
|
|
708
713
|
export function dayOfYear(d: IDateTime) {
|
|
@@ -717,11 +722,11 @@ export function dayOfYear(d: IDateTime) {
|
|
|
717
722
|
|
|
718
723
|
export function add(d: IDateTime, ts: number) {
|
|
719
724
|
const newDate = DateTime(d.getTime() + ts, d.kind);
|
|
720
|
-
if (d.kind !==
|
|
725
|
+
if (d.kind !== DateTimeKind.Utc) {
|
|
721
726
|
const oldTzOffset = d.getTimezoneOffset();
|
|
722
727
|
const newTzOffset = newDate.getTimezoneOffset();
|
|
723
728
|
return oldTzOffset !== newTzOffset
|
|
724
|
-
? DateTime(newDate.getTime() + (newTzOffset - oldTzOffset) *
|
|
729
|
+
? DateTime(newDate.getTime() + (newTzOffset - oldTzOffset) * 60_000, d.kind)
|
|
725
730
|
: newDate;
|
|
726
731
|
} else {
|
|
727
732
|
return newDate;
|
|
@@ -737,7 +742,7 @@ export function addHours(d: IDateTime, v: number) {
|
|
|
737
742
|
}
|
|
738
743
|
|
|
739
744
|
export function addMinutes(d: IDateTime, v: number) {
|
|
740
|
-
return add(d, v *
|
|
745
|
+
return add(d, v * 60_000);
|
|
741
746
|
}
|
|
742
747
|
|
|
743
748
|
export function addSeconds(d: IDateTime, v: number) {
|
package/DateOffset.ts
CHANGED
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
* Basically; invariant: date.getTime() always return UTC time.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { int64, fromFloat64, toFloat64 } from "./BigInt.
|
|
17
|
-
import DateTime, { create as createDate, dateOffsetToString, daysInMonth, parseRaw, ticksToUnixEpochMilliseconds, unixEpochMillisecondsToTicks } from "./Date.
|
|
18
|
-
import { FSharpRef } from "./Types.
|
|
19
|
-
import { compareDates,
|
|
16
|
+
import { int64, fromFloat64, toFloat64 } from "./BigInt.ts";
|
|
17
|
+
import DateTime, { create as createDate, dateOffsetToString, daysInMonth, parseRaw, ticksToUnixEpochMilliseconds, unixEpochMillisecondsToTicks } from "./Date.ts";
|
|
18
|
+
import { FSharpRef } from "./Types.ts";
|
|
19
|
+
import { Exception, compareDates, DateTimeKind, IDateTime, IDateTimeOffset, padWithZeros } from "./Util.ts";
|
|
20
20
|
|
|
21
21
|
export default function DateTimeOffset(value: number, offset?: number) {
|
|
22
22
|
checkOffsetInRange(offset);
|
|
23
23
|
const d = new Date(value) as IDateTimeOffset;
|
|
24
|
-
d.offset = offset != null ? offset : new Date().getTimezoneOffset() * -
|
|
24
|
+
d.offset = offset != null ? offset : new Date().getTimezoneOffset() * -60_000;
|
|
25
25
|
return d;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -31,11 +31,11 @@ export function offset(value: IDateTimeOffset): number {
|
|
|
31
31
|
|
|
32
32
|
function checkOffsetInRange(offset?: number) {
|
|
33
33
|
if (offset != null && offset !== 0) {
|
|
34
|
-
if (offset %
|
|
35
|
-
throw new
|
|
34
|
+
if (offset % 60_000 !== 0) {
|
|
35
|
+
throw new Exception("Offset must be specified in whole minutes.");
|
|
36
36
|
}
|
|
37
37
|
if (Math.abs(offset / 3600000) > 14) {
|
|
38
|
-
throw new
|
|
38
|
+
throw new Exception("Offset must be within plus or minus 14 hours.");
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -43,22 +43,22 @@ function checkOffsetInRange(offset?: number) {
|
|
|
43
43
|
export function fromDate(date: IDateTime, offset?: number) {
|
|
44
44
|
let offset2: number = 0;
|
|
45
45
|
switch (date.kind) {
|
|
46
|
-
case
|
|
46
|
+
case DateTimeKind.Utc:
|
|
47
47
|
if(offset != null && offset !== 0) {
|
|
48
|
-
throw new
|
|
48
|
+
throw new Exception("The UTC Offset for Utc DateTime instances must be 0.");
|
|
49
49
|
}
|
|
50
50
|
offset2 = 0;
|
|
51
51
|
break;
|
|
52
52
|
|
|
53
|
-
case
|
|
53
|
+
case DateTimeKind.Local:
|
|
54
54
|
offset2 = date.getTimezoneOffset() * -60_000;
|
|
55
55
|
if(offset != null && offset !== offset2) {
|
|
56
|
-
throw new
|
|
56
|
+
throw new Exception("The UTC Offset of the local dateTime parameter does not match the offset argument.");
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
break;
|
|
60
60
|
|
|
61
|
-
case
|
|
61
|
+
case DateTimeKind.Unspecified:
|
|
62
62
|
default:
|
|
63
63
|
if(offset == null) {
|
|
64
64
|
offset2 = date.getTimezoneOffset() * -60_000;
|
|
@@ -72,6 +72,10 @@ export function fromDate(date: IDateTime, offset?: number) {
|
|
|
72
72
|
return DateTimeOffset(date.getTime(), offset2);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
export function fromDateTime(dateOnly: IDateTime, timeOnly: number, offset: number) {
|
|
76
|
+
return DateTimeOffset(dateOnly.getTime() - offset + timeOnly, offset);
|
|
77
|
+
}
|
|
78
|
+
|
|
75
79
|
export function fromTicks(ticks: int64, offset: number) {
|
|
76
80
|
const ms = ticksToUnixEpochMilliseconds(ticks) - offset;
|
|
77
81
|
return DateTimeOffset(ms, offset);
|
|
@@ -102,8 +106,8 @@ export function maxValue() {
|
|
|
102
106
|
export function parse(str: string): IDateTimeOffset {
|
|
103
107
|
const [date, offsetMatch] = parseRaw(str);
|
|
104
108
|
const offset = offsetMatch == null
|
|
105
|
-
? date.getTimezoneOffset() * -
|
|
106
|
-
: (offsetMatch === "Z" ? 0 : offsetMatch *
|
|
109
|
+
? date.getTimezoneOffset() * -60_000
|
|
110
|
+
: (offsetMatch === "Z" ? 0 : offsetMatch * 60_000);
|
|
107
111
|
return DateTimeOffset(date.getTime(), offset);
|
|
108
112
|
}
|
|
109
113
|
|
|
@@ -125,101 +129,88 @@ export function create(
|
|
|
125
129
|
ms = 0;
|
|
126
130
|
}
|
|
127
131
|
checkOffsetInRange(offset);
|
|
128
|
-
let date
|
|
129
|
-
if (
|
|
130
|
-
date
|
|
131
|
-
if (year <= 99) {
|
|
132
|
-
date.setUTCFullYear(year, month - 1, day);
|
|
133
|
-
}
|
|
134
|
-
} else {
|
|
135
|
-
const str =
|
|
136
|
-
padWithZeros(year, 4) + "-" +
|
|
137
|
-
padWithZeros(month, 2) + "-" +
|
|
138
|
-
padWithZeros(day, 2) + "T" +
|
|
139
|
-
padWithZeros(h, 2) + ":" +
|
|
140
|
-
padWithZeros(m, 2) + ":" +
|
|
141
|
-
padWithZeros(s, 2) + "." +
|
|
142
|
-
padWithZeros(ms, 3) +
|
|
143
|
-
dateOffsetToString(offset);
|
|
144
|
-
date = new Date(str);
|
|
132
|
+
let date = new Date(Date.UTC(year, month - 1, day, h, m, s, ms) - offset);
|
|
133
|
+
if (year <= 99) {
|
|
134
|
+
date.setUTCFullYear(year, month - 1, day);
|
|
145
135
|
}
|
|
146
136
|
const dateValue = date.getTime();
|
|
147
137
|
if (isNaN(dateValue)) {
|
|
148
|
-
throw new
|
|
138
|
+
throw new Exception("The parameters describe an unrepresentable Date");
|
|
149
139
|
}
|
|
150
140
|
return DateTimeOffset(dateValue, offset);
|
|
151
141
|
}
|
|
152
142
|
|
|
153
143
|
export function now() {
|
|
154
144
|
const date = new Date();
|
|
155
|
-
const offset = date.getTimezoneOffset() * -
|
|
156
|
-
return DateTimeOffset(date.getTime(), offset);
|
|
145
|
+
const offset = date.getTimezoneOffset() * -60_000;
|
|
146
|
+
return DateTimeOffset(date.getTime() - offset, offset);
|
|
157
147
|
}
|
|
158
148
|
|
|
159
149
|
export function utcNow() {
|
|
160
|
-
const date =
|
|
150
|
+
const date = new Date();
|
|
151
|
+
// const offset = date.getTimezoneOffset() * -60_000;
|
|
161
152
|
return DateTimeOffset(date.getTime(), 0);
|
|
162
153
|
}
|
|
163
154
|
|
|
164
155
|
export function toUniversalTime(date: IDateTimeOffset): Date {
|
|
165
|
-
return DateTime(date.getTime(),
|
|
156
|
+
return DateTime(date.getTime(), DateTimeKind.Utc);
|
|
166
157
|
}
|
|
167
158
|
|
|
168
159
|
export function toLocalTime(date: IDateTimeOffset): Date {
|
|
169
|
-
return DateTime(date.getTime()
|
|
160
|
+
return DateTime(date.getTime(), DateTimeKind.Local);
|
|
170
161
|
}
|
|
171
162
|
|
|
172
163
|
export function localDateTime(date: IDateTimeOffset) : Date {
|
|
173
|
-
return DateTime(date.getTime(),
|
|
164
|
+
return DateTime(date.getTime(), DateTimeKind.Local);
|
|
174
165
|
}
|
|
175
166
|
|
|
176
167
|
export function timeOfDay(d: IDateTimeOffset) {
|
|
177
|
-
const d2 = new Date(d.getTime() + (d
|
|
168
|
+
const d2 = new Date(d.getTime() + offset(d));
|
|
178
169
|
return d2.getUTCHours() * 3600000
|
|
179
|
-
+ d2.getUTCMinutes() *
|
|
170
|
+
+ d2.getUTCMinutes() * 60_000
|
|
180
171
|
+ d2.getUTCSeconds() * 1000
|
|
181
172
|
+ d2.getUTCMilliseconds();
|
|
182
173
|
}
|
|
183
174
|
|
|
184
175
|
export function date(d: IDateTimeOffset) {
|
|
185
|
-
const d2 = new Date(d.getTime() + (d
|
|
176
|
+
const d2 = new Date(d.getTime() + offset(d));
|
|
186
177
|
return createDate(d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate(), 0, 0, 0, 0);
|
|
187
178
|
}
|
|
188
179
|
|
|
189
180
|
export function day(d: IDateTimeOffset) {
|
|
190
|
-
return new Date(d.getTime() + (d
|
|
181
|
+
return new Date(d.getTime() + offset(d)).getUTCDate();
|
|
191
182
|
}
|
|
192
183
|
|
|
193
184
|
export function hour(d: IDateTimeOffset) {
|
|
194
|
-
return new Date(d.getTime() + (d
|
|
185
|
+
return new Date(d.getTime() + offset(d)).getUTCHours();
|
|
195
186
|
}
|
|
196
187
|
|
|
197
188
|
export function millisecond(d: IDateTimeOffset) {
|
|
198
|
-
return new Date(d.getTime() + (d
|
|
189
|
+
return new Date(d.getTime() + offset(d)).getUTCMilliseconds();
|
|
199
190
|
}
|
|
200
191
|
|
|
201
192
|
export function minute(d: IDateTimeOffset) {
|
|
202
|
-
return new Date(d.getTime() + (d
|
|
193
|
+
return new Date(d.getTime() + offset(d)).getUTCMinutes();
|
|
203
194
|
}
|
|
204
195
|
|
|
205
196
|
export function month(d: IDateTimeOffset) {
|
|
206
|
-
return new Date(d.getTime() + (d
|
|
197
|
+
return new Date(d.getTime() + offset(d)).getUTCMonth() + 1;
|
|
207
198
|
}
|
|
208
199
|
|
|
209
200
|
export function second(d: IDateTimeOffset) {
|
|
210
|
-
return new Date(d.getTime() + (d
|
|
201
|
+
return new Date(d.getTime() + offset(d)).getUTCSeconds();
|
|
211
202
|
}
|
|
212
203
|
|
|
213
204
|
export function year(d: IDateTimeOffset) {
|
|
214
|
-
return new Date(d.getTime() + (d
|
|
205
|
+
return new Date(d.getTime() + offset(d)).getUTCFullYear();
|
|
215
206
|
}
|
|
216
207
|
|
|
217
208
|
export function dayOfWeek(d: IDateTimeOffset) {
|
|
218
|
-
return new Date(d.getTime() + (d
|
|
209
|
+
return new Date(d.getTime() + offset(d)).getUTCDay();
|
|
219
210
|
}
|
|
220
211
|
|
|
221
212
|
export function dayOfYear(d: IDateTimeOffset) {
|
|
222
|
-
const d2 = new Date(d.getTime() + (d
|
|
213
|
+
const d2 = new Date(d.getTime() + offset(d));
|
|
223
214
|
const _year = d2.getUTCFullYear();
|
|
224
215
|
const _month = d2.getUTCMonth() + 1;
|
|
225
216
|
let _day = d2.getUTCDate();
|
|
@@ -230,7 +221,7 @@ export function dayOfYear(d: IDateTimeOffset) {
|
|
|
230
221
|
}
|
|
231
222
|
|
|
232
223
|
export function add(d: IDateTimeOffset, ts: number) {
|
|
233
|
-
return DateTimeOffset(d.getTime() + ts, (d
|
|
224
|
+
return DateTimeOffset(d.getTime() + ts, offset(d));
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
export function addDays(d: IDateTimeOffset, v: number) {
|
|
@@ -242,7 +233,7 @@ export function addHours(d: IDateTimeOffset, v: number) {
|
|
|
242
233
|
}
|
|
243
234
|
|
|
244
235
|
export function addMinutes(d: IDateTimeOffset, v: number) {
|
|
245
|
-
return add(d, v *
|
|
236
|
+
return add(d, v * 60_000);
|
|
246
237
|
}
|
|
247
238
|
|
|
248
239
|
export function addSeconds(d: IDateTimeOffset, v: number) {
|
|
@@ -263,11 +254,11 @@ export function addYears(d: IDateTimeOffset, v: number) {
|
|
|
263
254
|
const _daysInMonth = daysInMonth(newYear, newMonth);
|
|
264
255
|
const newDay = Math.min(_daysInMonth, d.getUTCDate());
|
|
265
256
|
return create(newYear, newMonth, newDay, d.getUTCHours(), d.getUTCMinutes(),
|
|
266
|
-
d.getUTCSeconds(), d.getUTCMilliseconds(), (d
|
|
257
|
+
d.getUTCSeconds(), d.getUTCMilliseconds(), offset(d));
|
|
267
258
|
}
|
|
268
259
|
|
|
269
260
|
export function addMonths(d: IDateTimeOffset, v: number) {
|
|
270
|
-
const d2 = new Date(d.getTime() + (d
|
|
261
|
+
const d2 = new Date(d.getTime() + offset(d));
|
|
271
262
|
let newMonth = d2.getUTCMonth() + 1 + v;
|
|
272
263
|
let newMonth_ = 0;
|
|
273
264
|
let yearOffset = 0;
|
|
@@ -284,12 +275,12 @@ export function addMonths(d: IDateTimeOffset, v: number) {
|
|
|
284
275
|
const _daysInMonth = daysInMonth(newYear, newMonth);
|
|
285
276
|
const newDay = Math.min(_daysInMonth, d2.getUTCDate());
|
|
286
277
|
return create(newYear, newMonth, newDay, d2.getUTCHours(), d2.getUTCMinutes(),
|
|
287
|
-
d2.getUTCSeconds(), d2.getUTCMilliseconds(), (d
|
|
278
|
+
d2.getUTCSeconds(), d2.getUTCMilliseconds(), offset(d));
|
|
288
279
|
}
|
|
289
280
|
|
|
290
281
|
export function subtract<Input extends number | IDateTimeOffset, Output = Input extends number ? IDateTimeOffset : number>(d: IDateTimeOffset, that: Input): Output {
|
|
291
282
|
return typeof that === "number"
|
|
292
|
-
? DateTimeOffset(d.getTime() - that, (d
|
|
283
|
+
? DateTimeOffset(d.getTime() - that, offset(d)) as Output
|
|
293
284
|
: d.getTime() - that.getTime() as Output;
|
|
294
285
|
}
|
|
295
286
|
|