Skip to content

Commit d1b1b14

Browse files
authored
Fix toString for Date/DateTime (#362)
Min date was incorrectly toStringing to `1-01-01` instead of `0001-01-01`. Fix and apply consistent padding to date-based toString operations.
1 parent 041ed96 commit d1b1b14

5 files changed

Lines changed: 68 additions & 65 deletions

File tree

examples/browser/cql4browsers.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,9 +1327,6 @@ class DateTime extends AbstractDate {
13271327
toJSON() {
13281328
return this.toString();
13291329
}
1330-
_pad(num) {
1331-
return String('0' + num).slice(-2);
1332-
}
13331330
toString() {
13341331
if (this.isTime()) {
13351332
return this.toStringTime();
@@ -1341,13 +1338,13 @@ class DateTime extends AbstractDate {
13411338
toStringTime() {
13421339
let str = '';
13431340
if (this.hour != null) {
1344-
str += this._pad(this.hour);
1341+
str += String(this.hour).padStart(2, '0');
13451342
if (this.minute != null) {
1346-
str += ':' + this._pad(this.minute);
1343+
str += ':' + String(this.minute).padStart(2, '0');
13471344
if (this.second != null) {
1348-
str += ':' + this._pad(this.second);
1345+
str += ':' + String(this.second).padStart(2, '0');
13491346
if (this.millisecond != null) {
1350-
str += '.' + String('00' + this.millisecond).slice(-3);
1347+
str += '.' + String(this.millisecond).padStart(3, '0');
13511348
}
13521349
}
13531350
}
@@ -1357,19 +1354,19 @@ class DateTime extends AbstractDate {
13571354
toStringDateTime() {
13581355
let str = '';
13591356
if (this.year != null) {
1360-
str += this.year;
1357+
str += String(this.year).padStart(4, '0');
13611358
if (this.month != null) {
1362-
str += '-' + this._pad(this.month);
1359+
str += '-' + String(this.month).padStart(2, '0');
13631360
if (this.day != null) {
1364-
str += '-' + this._pad(this.day);
1361+
str += '-' + String(this.day).padStart(2, '0');
13651362
if (this.hour != null) {
1366-
str += 'T' + this._pad(this.hour);
1363+
str += 'T' + String(this.hour).padStart(2, '0');
13671364
if (this.minute != null) {
1368-
str += ':' + this._pad(this.minute);
1365+
str += ':' + String(this.minute).padStart(2, '0');
13691366
if (this.second != null) {
1370-
str += ':' + this._pad(this.second);
1367+
str += ':' + String(this.second).padStart(2, '0');
13711368
if (this.millisecond != null) {
1372-
str += '.' + String('00' + this.millisecond).slice(-3);
1369+
str += '.' + String(this.millisecond).padStart(3, '0');
13731370
}
13741371
}
13751372
}
@@ -1380,9 +1377,9 @@ class DateTime extends AbstractDate {
13801377
if (str.indexOf('T') !== -1 && this.timezoneOffset != null) {
13811378
str += this.timezoneOffset < 0 ? '-' : '+';
13821379
const offsetHours = Math.floor(Math.abs(this.timezoneOffset));
1383-
str += this._pad(offsetHours);
1380+
str += String(offsetHours).padStart(2, '0');
13841381
const offsetMin = (Math.abs(this.timezoneOffset) - offsetHours) * 60;
1385-
str += ':' + this._pad(offsetMin);
1382+
str += ':' + String(offsetMin).padStart(2, '0');
13861383
}
13871384
return str;
13881385
}
@@ -1589,7 +1586,7 @@ class Date extends AbstractDate {
15891586
toString() {
15901587
let str = '';
15911588
if (this.year != null) {
1592-
str += this.year.toString();
1589+
str += this.year.toString().padStart(4, '0');
15931590
if (this.month != null) {
15941591
str += '-' + this.month.toString().padStart(2, '0');
15951592
if (this.day != null) {

package-lock.json

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

src/datatypes/datetime.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -934,10 +934,6 @@ export class DateTime extends AbstractDate {
934934
return this.toString();
935935
}
936936

937-
_pad(num: number) {
938-
return String('0' + num).slice(-2);
939-
}
940-
941937
toString() {
942938
if (this.isTime()) {
943939
return this.toStringTime();
@@ -949,13 +945,13 @@ export class DateTime extends AbstractDate {
949945
toStringTime() {
950946
let str = '';
951947
if (this.hour != null) {
952-
str += this._pad(this.hour);
948+
str += String(this.hour).padStart(2, '0');
953949
if (this.minute != null) {
954-
str += ':' + this._pad(this.minute);
950+
str += ':' + String(this.minute).padStart(2, '0');
955951
if (this.second != null) {
956-
str += ':' + this._pad(this.second);
952+
str += ':' + String(this.second).padStart(2, '0');
957953
if (this.millisecond != null) {
958-
str += '.' + String('00' + this.millisecond).slice(-3);
954+
str += '.' + String(this.millisecond).padStart(3, '0');
959955
}
960956
}
961957
}
@@ -967,19 +963,19 @@ export class DateTime extends AbstractDate {
967963
toStringDateTime() {
968964
let str = '';
969965
if (this.year != null) {
970-
str += this.year;
966+
str += String(this.year).padStart(4, '0');
971967
if (this.month != null) {
972-
str += '-' + this._pad(this.month);
968+
str += '-' + String(this.month).padStart(2, '0');
973969
if (this.day != null) {
974-
str += '-' + this._pad(this.day);
970+
str += '-' + String(this.day).padStart(2, '0');
975971
if (this.hour != null) {
976-
str += 'T' + this._pad(this.hour);
972+
str += 'T' + String(this.hour).padStart(2, '0');
977973
if (this.minute != null) {
978-
str += ':' + this._pad(this.minute);
974+
str += ':' + String(this.minute).padStart(2, '0');
979975
if (this.second != null) {
980-
str += ':' + this._pad(this.second);
976+
str += ':' + String(this.second).padStart(2, '0');
981977
if (this.millisecond != null) {
982-
str += '.' + String('00' + this.millisecond).slice(-3);
978+
str += '.' + String(this.millisecond).padStart(3, '0');
983979
}
984980
}
985981
}
@@ -991,9 +987,9 @@ export class DateTime extends AbstractDate {
991987
if (str.indexOf('T') !== -1 && this.timezoneOffset != null) {
992988
str += this.timezoneOffset < 0 ? '-' : '+';
993989
const offsetHours = Math.floor(Math.abs(this.timezoneOffset));
994-
str += this._pad(offsetHours);
990+
str += String(offsetHours).padStart(2, '0');
995991
const offsetMin = (Math.abs(this.timezoneOffset) - offsetHours) * 60;
996-
str += ':' + this._pad(offsetMin);
992+
str += ':' + String(offsetMin).padStart(2, '0');
997993
}
998994

999995
return str;
@@ -1218,7 +1214,7 @@ export class Date extends AbstractDate {
12181214
toString() {
12191215
let str = '';
12201216
if (this.year != null) {
1221-
str += this.year.toString();
1217+
str += this.year.toString().padStart(4, '0');
12221218
if (this.month != null) {
12231219
str += '-' + this.month.toString().padStart(2, '0');
12241220
if (this.day != null) {

test/datatypes/date-test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as luxon from 'luxon';
22
import should from 'should';
3-
import { Date, DateTime } from '../../src/datatypes/datetime';
3+
import { Date, DateTime, MAX_DATE_VALUE, MIN_DATE_VALUE } from '../../src/datatypes/datetime';
44
import { Uncertainty } from '../../src/datatypes/uncertainty';
55
import { jsDate } from '../../src/util/util';
66

@@ -49,6 +49,11 @@ describe('Date', () => {
4949
d.toString().should.eql('2012-10-25');
5050
});
5151

52+
it('should toString min and max values', () => {
53+
MIN_DATE_VALUE.toString().should.eql('0001-01-01');
54+
MAX_DATE_VALUE.toString().should.eql('9999-12-31');
55+
});
56+
5257
it('should return null when parsing non-string', () => should(Date.parse(20121025)).be.null());
5358

5459
it('should return null when parsing invalid string format', () =>

test/datatypes/datetime-test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
22
import * as luxon from 'luxon';
33
import should from 'should';
4-
import { DateTime } from '../../src/datatypes/datetime';
4+
import { DateTime, MAX_DATETIME_VALUE, MIN_DATETIME_VALUE } from '../../src/datatypes/datetime';
55
import { Uncertainty } from '../../src/datatypes/uncertainty';
66

77
const tzDate = function (
@@ -187,6 +187,11 @@ describe('DateTime', () => {
187187
d.toString().should.eql('2012-10-25T12:55:14.953-05:00');
188188
});
189189

190+
it('should toString min and max values', () => {
191+
MIN_DATETIME_VALUE.toString().should.match(/^0001-01-01T00:00:00\.000([+-]\d\d:\d\d|Z)$/);
192+
MAX_DATETIME_VALUE.toString().should.match(/^9999-12-31T23:59:59\.999([+-]\d\d:\d\d|Z)$/);
193+
});
194+
190195
it('should be null when parsing non-string', () => should(DateTime.parse(20121025)).be.null());
191196

192197
it('should be null when parsing invalid string format', () =>

0 commit comments

Comments
 (0)