Skip to content

Commit 3e97393

Browse files
committed
WIP of better CQL Decimal support, checkpoint 2
1 parent d939b77 commit 3e97393

43 files changed

Lines changed: 7061 additions & 1446 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/browser/cql4browsers.js

Lines changed: 5728 additions & 365 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
},
9595
"dependencies": {
9696
"@lhncbc/ucum-lhc": "^7.1.9",
97+
"decimal.js": "^10.6.0",
9798
"immutable": "^5.1.6",
9899
"luxon": "^3.7.2"
99100
},

src/datatypes/datetime.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
MIN_DATETIME_VALUE_STRING,
2121
MIN_TIME_VALUE_STRING
2222
} from '../util/limits';
23+
import { Decimal } from './decimal';
2324

2425
// It's easiest and most performant to organize formats by length of the supported strings.
2526
// This way we can test strings only against the formats that have a chance of working.
@@ -530,7 +531,7 @@ export class DateTime extends AbstractDate {
530531
minute: number | null;
531532
second: number | null;
532533
millisecond: number | null;
533-
timezoneOffset: number | null;
534+
timezoneOffset: Decimal | null;
534535

535536
static readonly Unit = {
536537
YEAR: 'year',
@@ -600,13 +601,19 @@ export class DateTime extends AbstractDate {
600601
}
601602

602603
// TODO: Note: using the jsDate type causes issues, fix later
603-
static fromJSDate(date: any, timezoneOffset?: any) {
604+
static fromJSDate(date: any, timezoneOffset?: number | string | Decimal) {
604605
//This is from a JS Date, not a CQL Date
605606
if (date instanceof DateTime) {
606607
return date;
607608
}
608609
if (timezoneOffset != null) {
609-
date = new jsDate(date.getTime() + timezoneOffset * 60 * 60 * 1000);
610+
let tzOffset: number;
611+
if (timezoneOffset instanceof Decimal) {
612+
tzOffset = timezoneOffset.toNumber();
613+
} else {
614+
tzOffset = +timezoneOffset;
615+
}
616+
date = new jsDate(date.getTime() + tzOffset * 60 * 60 * 1000);
610617
return new DateTime(
611618
date.getUTCFullYear(),
612619
date.getUTCMonth() + 1,
@@ -615,7 +622,7 @@ export class DateTime extends AbstractDate {
615622
date.getUTCMinutes(),
616623
date.getUTCSeconds(),
617624
date.getUTCMilliseconds(),
618-
timezoneOffset
625+
tzOffset
619626
);
620627
} else {
621628
return new DateTime(
@@ -642,7 +649,7 @@ export class DateTime extends AbstractDate {
642649
luxonDT.minute,
643650
luxonDT.second,
644651
luxonDT.millisecond,
645-
luxonDT.offset / 60
652+
Decimal.from(luxonDT.offset / 60)
646653
);
647654
}
648655

@@ -654,7 +661,7 @@ export class DateTime extends AbstractDate {
654661
minute: number | null = null,
655662
second: number | null = null,
656663
millisecond: number | null = null,
657-
timezoneOffset?: number | null
664+
timezoneOffset?: Decimal | number | null
658665
) {
659666
// from the spec: If no timezone is specified, the timezone of the evaluation request timestamp is used.
660667
// NOTE: timezoneOffset will be explicitly null for the Time overload, whereas
@@ -665,9 +672,11 @@ export class DateTime extends AbstractDate {
665672
this.second = second;
666673
this.millisecond = millisecond;
667674
if (timezoneOffset === undefined) {
668-
this.timezoneOffset = (new jsDate().getTimezoneOffset() / 60) * -1;
675+
this.timezoneOffset = Decimal.from((new jsDate().getTimezoneOffset() / 60) * -1);
676+
} else if (timezoneOffset === null) {
677+
this.timezoneOffset = null;
669678
} else {
670-
this.timezoneOffset = timezoneOffset;
679+
this.timezoneOffset = Decimal.from(timezoneOffset);
671680
}
672681
}
673682

@@ -870,7 +879,7 @@ export class DateTime extends AbstractDate {
870879
toLuxonDateTime() {
871880
const offsetMins =
872881
this.timezoneOffset != null
873-
? this.timezoneOffset * 60
882+
? this.timezoneOffset.toNumber() * 60
874883
: new jsDate().getTimezoneOffset() * -1;
875884
return LuxonDateTime.fromObject(
876885
{
@@ -959,10 +968,11 @@ export class DateTime extends AbstractDate {
959968
}
960969

961970
if (str.indexOf('T') !== -1 && this.timezoneOffset != null) {
962-
str += this.timezoneOffset < 0 ? '-' : '+';
963-
const offsetHours = Math.floor(Math.abs(this.timezoneOffset));
971+
const tzOffset = this.timezoneOffset.toNumber();
972+
str += tzOffset < 0 ? '-' : '+';
973+
const offsetHours = Math.floor(Math.abs(tzOffset));
964974
str += String(offsetHours).padStart(2, '0');
965-
const offsetMin = (Math.abs(this.timezoneOffset) - offsetHours) * 60;
975+
const offsetMin = (Math.abs(tzOffset) - offsetHours) * 60;
966976
str += ':' + String(offsetMin).padStart(2, '0');
967977
}
968978

@@ -1203,7 +1213,7 @@ export class Date extends AbstractDate {
12031213
return str;
12041214
}
12051215

1206-
getDateTime(timeZoneOffset?: number | null) {
1216+
getDateTime(timeZoneOffset?: Decimal | null) {
12071217
// from the spec: the result will be a DateTime with the time components unspecified,
12081218
// except for the timezone offset, which will be set to the timezone offset of the evaluation
12091219
// request timestamp. (this last part is achieved by passing in the timeZoneOffset from the context)

0 commit comments

Comments
 (0)