From e63a7cae98d2a369ce36df5c618659ddf2a00864 Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Thu, 27 May 2021 23:15:00 +0200 Subject: [PATCH] Parsing ISO date string manually in search queries, also replacing all date to UTC dates #312 --- src/common/SearchQueryParser.ts | 22 +++++++++++++++++----- test/common/unit/SearchQueryParser.ts | 16 ++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/common/SearchQueryParser.ts b/src/common/SearchQueryParser.ts index c411d7af..6df897f4 100644 --- a/src/common/SearchQueryParser.ts +++ b/src/common/SearchQueryParser.ts @@ -62,6 +62,7 @@ export class SearchQueryParser { public static stringifyDate(time: number): string { const date = new Date(time); + // simplify date with yeah only if its first of jan if (date.getMonth() === 0 && date.getDate() === 1) { return date.getFullYear().toString(); @@ -78,12 +79,23 @@ export class SearchQueryParser { } // it is the year only if (text.length === 4) { - const d = new Date(2000, 0, 1); - d.setFullYear(parseInt(text, 10)); - return d.getTime(); + return Date.UTC(parseInt(text, 10), 0, 1, 0, 0, 0, 0); } - const timestamp = Date.parse(text); - if (isNaN(timestamp)) { + let timestamp = null; + // Parsing ISO string + try { + const parts = text.split('-').map(t => parseInt(t, 10)); + if (parts && parts.length === 3) { + timestamp = (Date.UTC(parts[0], parts[1] - 1, parts[2])); // Note: months are 0-based + } + } catch (e) { + } + // If it could not parse as ISO string, try our luck with Date.parse + // https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results + if (timestamp === null) { + timestamp = Date.parse(text); + } + if (isNaN(timestamp) || timestamp === null) { throw new Error('Cannot parse date: ' + text); } diff --git a/test/common/unit/SearchQueryParser.ts b/test/common/unit/SearchQueryParser.ts index 442ac117..d254665a 100644 --- a/test/common/unit/SearchQueryParser.ts +++ b/test/common/unit/SearchQueryParser.ts @@ -85,20 +85,20 @@ describe('SearchQueryParser', () => { }); it('Date search', () => { - check({type: SearchQueryTypes.from_date, value: (new Date(2020, 1, 10)).getTime()} as FromDateSearch); - check({type: SearchQueryTypes.from_date, value: (new Date(2020, 1, 1)).getTime()} as FromDateSearch); - check({type: SearchQueryTypes.to_date, value: (new Date(2020, 1, 20)).getTime()} as ToDateSearch); - check({type: SearchQueryTypes.to_date, value: (new Date(2020, 1, 1)).getTime()} as ToDateSearch); - check({type: SearchQueryTypes.from_date, value: (new Date(2020, 1, 1)).getTime(), negate: true} as FromDateSearch); - check({type: SearchQueryTypes.to_date, value: (new Date(2020, 1, 1)).getTime(), negate: true} as ToDateSearch); + check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 10))} as FromDateSearch); + check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 1))} as FromDateSearch); + check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 20))} as ToDateSearch); + check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 1))} as ToDateSearch); + check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 1)), negate: true} as FromDateSearch); + check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 1)), negate: true} as ToDateSearch); const parser = new SearchQueryParser(queryKeywords); // test if date gets simplified on 1st of Jan. - let query: RangeSearch = {type: SearchQueryTypes.to_date, value: (new Date(2020, 0, 1)).getTime()} as ToDateSearch; + let query: RangeSearch = {type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 0, 1))} as ToDateSearch; expect(parser.parse(queryKeywords.to + ':' + (new Date(query.value)).getFullYear())) .to.deep.equals(query, parser.stringify(query)); - query = ({type: SearchQueryTypes.from_date, value: (new Date(2020, 0, 1)).getTime()} as FromDateSearch); + query = ({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 0, 1))} as FromDateSearch); expect(parser.parse(queryKeywords.from + ':' + (new Date(query.value)).getFullYear())) .to.deep.equals(query, parser.stringify(query));