Skip to content

Commit

Permalink
Fix: ISO format default to local timezone instead of UTC
Browse files Browse the repository at this point in the history
  • Loading branch information
Wanasit Tanakitrungruang committed Sep 16, 2024
1 parent d61f933 commit 696d247
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 60 deletions.
62 changes: 30 additions & 32 deletions src/common/parsers/ISOFormatParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const PATTERN = new RegExp(
"(?:" +
":([0-9]{1,2})(?:\\.(\\d{1,4}))?" +
")?" + // :ss.s
"(?:" +
"(" +
"Z|([+-]\\d{2}):?(\\d{2})?" +
")?" + // TZD (Z or ±hh:mm or ±hhmm or ±hh)
")?" +
Expand All @@ -33,53 +33,51 @@ const HOUR_NUMBER_GROUP = 4;
const MINUTE_NUMBER_GROUP = 5;
const SECOND_NUMBER_GROUP = 6;
const MILLISECOND_NUMBER_GROUP = 7;
const TZD_HOUR_OFFSET_GROUP = 8;
const TZD_MINUTE_OFFSET_GROUP = 9;
const TZD_GROUP = 8;
const TZD_HOUR_OFFSET_GROUP = 9;
const TZD_MINUTE_OFFSET_GROUP = 10;

export default class ISOFormatParser extends AbstractParserWithWordBoundaryChecking {
innerPattern(): RegExp {
return PATTERN;
}

innerExtract(context: ParsingContext, match: RegExpMatchArray) {
const components: { [component in Component]?: number } = {};
components["year"] = parseInt(match[YEAR_NUMBER_GROUP]);
components["month"] = parseInt(match[MONTH_NUMBER_GROUP]);
components["day"] = parseInt(match[DATE_NUMBER_GROUP]);

const components = context.createParsingComponents({
"year": parseInt(match[YEAR_NUMBER_GROUP]),
"month": parseInt(match[MONTH_NUMBER_GROUP]),
"day": parseInt(match[DATE_NUMBER_GROUP]),
});
if (match[HOUR_NUMBER_GROUP] != null) {
components["hour"] = parseInt(match[HOUR_NUMBER_GROUP]);
components["minute"] = parseInt(match[MINUTE_NUMBER_GROUP]);
components.assign("hour", parseInt(match[HOUR_NUMBER_GROUP]));
components.assign("minute", parseInt(match[MINUTE_NUMBER_GROUP]));

if (match[SECOND_NUMBER_GROUP] != null) {
components["second"] = parseInt(match[SECOND_NUMBER_GROUP]);
components.assign("second", parseInt(match[SECOND_NUMBER_GROUP]));
}

if (match[MILLISECOND_NUMBER_GROUP] != null) {
components["millisecond"] = parseInt(match[MILLISECOND_NUMBER_GROUP]);
components.assign("millisecond", parseInt(match[MILLISECOND_NUMBER_GROUP]));
}

if (match[TZD_HOUR_OFFSET_GROUP] == null) {
components["timezoneOffset"] = 0;
} else {
const hourOffset = parseInt(match[TZD_HOUR_OFFSET_GROUP]);

let minuteOffset = 0;
if (match[TZD_MINUTE_OFFSET_GROUP] != null) {
minuteOffset = parseInt(match[TZD_MINUTE_OFFSET_GROUP]);
if (match[TZD_GROUP] != null) {
// The Zulu time zone (Z) is equivalent to UTC
let offset = 0;
if (match[TZD_HOUR_OFFSET_GROUP]) {
const hourOffset = parseInt(match[TZD_HOUR_OFFSET_GROUP]);
let minuteOffset = 0;
if (match[TZD_MINUTE_OFFSET_GROUP] != null) {
minuteOffset = parseInt(match[TZD_MINUTE_OFFSET_GROUP]);
}
offset = hourOffset * 60;
if (offset < 0) {
offset -= minuteOffset;
} else {
offset += minuteOffset;
}
}

let offset = hourOffset * 60;
if (offset < 0) {
offset -= minuteOffset;
} else {
offset += minuteOffset;
}

components["timezoneOffset"] = offset;
components.assign("timezoneOffset", offset);
}
}

return components;
return components.addTag("parser/ISOFormatParser");
}
}
58 changes: 30 additions & 28 deletions test/en/en_inter_std.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,6 @@ test("Test - Single Expression", function () {
expect(result.start).toBeDate(new Date(784043130000));
});

testSingleCase(chrono, "1994-11-05T13:15:30", new Date(2012, 7, 8), (result) => {
expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(1994);
expect(result.start.get("month")).toBe(11);
expect(result.start.get("day")).toBe(5);
expect(result.start.get("hour")).toBe(13);
expect(result.start.get("minute")).toBe(15);
expect(result.start.get("second")).toBe(30);
expect(result.start.get("timezoneOffset")).toBe(0);
expect(result.text).toBe("1994-11-05T13:15:30");

expect(result.start).toBeDate(new Date(784041330000));
});

testSingleCase(chrono, "2015-07-31T12:00:00", new Date(2012, 7, 8), (result) => {
expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(2015);
expect(result.start.get("month")).toBe(7);
expect(result.start.get("day")).toBe(31);
expect(result.start.get("hour")).toBe(12);
expect(result.start.get("minute")).toBe(0);
expect(result.start.get("second")).toBe(0);
expect(result.start.get("timezoneOffset")).toBe(0);
expect(result.text).toBe("2015-07-31T12:00:00");

expect(result.start).toBeDate(new Date(1438344000000));
});

testSingleCase(chrono, "1994-11-05T13:15:30Z", new Date(2012, 7, 8), (result) => {
expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(1994);
Expand Down Expand Up @@ -114,3 +86,33 @@ test("Test - Single Expression", function () {
expect(result.start).toBeDate(new Date(1462661100487));
});
});

test("Test - Single Expression with local timezeon", function () {
testSingleCase(chrono, "1994-11-05T13:15:30", new Date(2012, 7, 8), (result) => {
expect(result.text).toBe("1994-11-05T13:15:30");
expect(result.start.get("year")).toBe(1994);
expect(result.start.get("month")).toBe(11);
expect(result.start.get("day")).toBe(5);
expect(result.start.get("hour")).toBe(13);
expect(result.start.get("minute")).toBe(15);
expect(result.start.get("second")).toBe(30);
expect(result.start.get("millisecond")).toBe(0);

expect(result.start.isCertain("timezoneOffset")).toBe(false);
expect(result.start).toBeDate(new Date("1994-11-05T13:15:30"));
});

testSingleCase(chrono, "2015-07-31T12:00:00", new Date(2012, 7, 8), (result) => {
expect(result.text).toBe("2015-07-31T12:00:00");
expect(result.start.get("year")).toBe(2015);
expect(result.start.get("month")).toBe(7);
expect(result.start.get("day")).toBe(31);
expect(result.start.get("hour")).toBe(12);
expect(result.start.get("minute")).toBe(0);
expect(result.start.get("second")).toBe(0);
expect(result.start.get("millisecond")).toBe(0);

expect(result.start.isCertain("timezoneOffset")).toBe(false);
expect(result.start).toBeDate(new Date("2015-07-31T12:00:00"));
});
});
2 changes: 2 additions & 0 deletions test/system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,6 @@ test("Test - Compare with native js", () => {
testByCompareWithNative("Fri, 31 Mar 2000 07:00:00 UTC");

testByCompareWithNative("2014-12-14T18:22:14.759Z");

testByCompareWithNative("2024-01-01T00:00");
});

0 comments on commit 696d247

Please sign in to comment.