From fc90e6e0d0c3138b95c25b9a8892c537c839487d Mon Sep 17 00:00:00 2001 From: Radoslaw Szwajkowski Date: Tue, 17 Oct 2023 23:00:04 +0200 Subject: [PATCH] Switch to closed time interval Signed-off-by: Radoslaw Szwajkowski --- .../src/components/Filter/DateRangeFilter.tsx | 5 +++-- .../common/src/components/FilterGroup/matchers.ts | 4 ++-- packages/common/src/utils/__tests__/dates.test.ts | 13 ++++++++----- packages/common/src/utils/dates.ts | 8 +++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/common/src/components/Filter/DateRangeFilter.tsx b/packages/common/src/components/Filter/DateRangeFilter.tsx index d756fa1b9..4cacf349e 100644 --- a/packages/common/src/components/Filter/DateRangeFilter.tsx +++ b/packages/common/src/components/Filter/DateRangeFilter.tsx @@ -21,8 +21,8 @@ import { import { FilterTypeProps } from './types'; /** - * This Filter type enables selecting an exclusive date range. - * Precisely given range [A,B) a date X in the range if A <= X < B. + * This Filter type enables selecting an closed date range. + * Precisely given range [A,B] a date X in the range if A <= X <= B. * * **FilterTypeProps are interpreted as follows**:
* 1) selectedFilters - date range encoded as ISO 8601 time interval string ("dateFrom/dateTo"). Only date part is used (no time).
@@ -93,6 +93,7 @@ export const DateRangeFilter = ({ DateTime.fromJSDate(date).toISODate()} dateParse={(str) => DateTime.fromISO(str).toJSDate()} onChange={onFromDateChange} diff --git a/packages/common/src/components/FilterGroup/matchers.ts b/packages/common/src/components/FilterGroup/matchers.ts index e160d7210..6cc517c56 100644 --- a/packages/common/src/components/FilterGroup/matchers.ts +++ b/packages/common/src/components/FilterGroup/matchers.ts @@ -1,6 +1,6 @@ import jsonpath from 'jsonpath'; -import { areSameDayInUTCZero, isInRange, ResourceField } from '../../utils'; +import { areSameDayInUTCZero, isInClosedRange, ResourceField } from '../../utils'; import { DateFilter, DateRangeFilter, @@ -110,7 +110,7 @@ const dateMatcher = { const dateRangeMatcher = { filterType: 'dateRange', - matchValue: (value: string) => (filter: string) => isInRange(filter, value), + matchValue: (value: string) => (filter: string) => isInClosedRange(filter, value), }; const sliderMatcher = { diff --git a/packages/common/src/utils/__tests__/dates.test.ts b/packages/common/src/utils/__tests__/dates.test.ts index 727685fb7..a0a53aea7 100644 --- a/packages/common/src/utils/__tests__/dates.test.ts +++ b/packages/common/src/utils/__tests__/dates.test.ts @@ -2,7 +2,7 @@ import { areSameDayInUTCZero, changeFormatToISODate, changeTimeZoneToUTCZero, - isInRange, + isInClosedRange, isValidDate, isValidInterval, parseISOtoJSDate, @@ -79,12 +79,15 @@ describe('areSameDayInUTCZero', () => { }); }); -describe('isInRange', () => { - test('date in range', () => { - expect(isInRange('2023-10-30/2023-10-31', '2023-10-31T01:30:00.000+02:00')).toBeTruthy(); +describe('isInClosedRange', () => { + test('date in range(positive TZ offset)', () => { + expect(isInClosedRange('2023-10-30/2023-10-31', '2023-11-01T01:30:00.000+02:00')).toBeTruthy(); + }); + test('date after range (negative TZ offset)', () => { + expect(isInClosedRange('2023-10-30/2023-10-31', '2023-10-31T22:30:00.000-02:00')).toBeFalsy(); }); test('date before range', () => { - expect(isInRange('2023-10-31/2023-11-01', '2023-10-31T01:30:00.000+02:00')).toBeFalsy(); + expect(isInClosedRange('2023-10-31/2023-11-01', '2023-10-31T01:30:00.000+02:00')).toBeFalsy(); }); }); diff --git a/packages/common/src/utils/dates.ts b/packages/common/src/utils/dates.ts index 53e24e9d8..c67c7a452 100644 --- a/packages/common/src/utils/dates.ts +++ b/packages/common/src/utils/dates.ts @@ -59,14 +59,16 @@ export const areSameDayInUTCZero = (dateTime: string, calendarDate: string): boo /** * - * @param interval ISO time interval with date part only (no time, no time zone) + * @param interval ISO time interval with date part only (no time, no time zone) interpreted as closed range (both start and and included) * @param date ISO date time * @returns true if the provided date is in the time interval */ -export const isInRange = (interval: string, date: string): boolean => - Interval.fromISO(interval).contains( +export const isInClosedRange = (interval: string, date: string): boolean => { + const { start, end } = Interval.fromISO(interval); + return Interval.fromDateTimes(start, end.plus({ days: 1 })).contains( DateTime.fromISO(date).toUTC().setZone('local', { keepCalendarTime: true }), ); +}; /** *