Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
feat: allow milliseconds in date queries (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
carvantes authored Apr 8, 2021
1 parent b082508 commit 86dbccd
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 53 deletions.
107 changes: 59 additions & 48 deletions src/QueryBuilder/typeQueries/dateQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,65 +14,76 @@ describe('parseDateSearchParam', () => {
describe('valid inputs', () => {
test('YYYY', () => {
expect(parseDateSearchParam('2020')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-12-31T23:59:59.000Z,
"start": 2020-01-01T00:00:00.000Z,
},
}
`);
Object {
"prefix": "eq",
"range": Object {
"end": 2020-12-31T23:59:59.999Z,
"start": 2020-01-01T00:00:00.000Z,
},
}
`);
});
test('YYYY-MM', () => {
expect(parseDateSearchParam('2020-02')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-29T23:59:59.000Z,
"start": 2020-02-01T00:00:00.000Z,
},
}
`);
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-29T23:59:59.999Z,
"start": 2020-02-01T00:00:00.000Z,
},
}
`);
});
test('YYYY-MM-DD', () => {
expect(parseDateSearchParam('2020-02-02')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T23:59:59.000Z,
"start": 2020-02-02T00:00:00.000Z,
},
}
`);
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T23:59:59.999Z,
"start": 2020-02-02T00:00:00.000Z,
},
}
`);
});
test('YYYY-MM-DDT:hh:mm', () => {
expect(parseDateSearchParam('2020-02-02T07:07')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:59.000Z,
"start": 2020-02-02T07:07:00.000Z,
},
}
`);
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:59.999Z,
"start": 2020-02-02T07:07:00.000Z,
},
}
`);
});
test('YYYY-MM-DDT:hh:mm:ss', () => {
expect(parseDateSearchParam('2020-02-02T07:07:07')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:07.000Z,
"start": 2020-02-02T07:07:07.000Z,
},
}
`);
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:07.999Z,
"start": 2020-02-02T07:07:07.000Z,
},
}
`);
});
test('YYYY-MM-DDT:hh:mm:ss.sss', () => {
expect(parseDateSearchParam('2020-02-02T07:07:07.777')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:07.777Z,
"start": 2020-02-02T07:07:07.777Z,
},
}
`);
});
test('YYYY-MM-DDT:hh:mm:ssZ', () => {
expect(parseDateSearchParam('2020-02-02T07:07:07Z')).toMatchInlineSnapshot(`
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T07:07:07.000Z,
"end": 2020-02-02T07:07:07.999Z,
"start": 2020-02-02T07:07:07.000Z,
},
}
Expand All @@ -83,7 +94,7 @@ describe('parseDateSearchParam', () => {
Object {
"prefix": "eq",
"range": Object {
"end": 2020-02-02T00:07:07.000Z,
"end": 2020-02-02T00:07:07.999Z,
"start": 2020-02-02T00:07:07.000Z,
},
}
Expand Down Expand Up @@ -114,7 +125,7 @@ describe('dateQuery', () => {
"range": Object {
"birthDate": Object {
"gte": 1999-09-09T00:00:00.000Z,
"lte": 1999-09-09T23:59:59.000Z,
"lte": 1999-09-09T23:59:59.999Z,
},
},
}
Expand All @@ -126,7 +137,7 @@ describe('dateQuery', () => {
"range": Object {
"birthDate": Object {
"gte": 1999-09-09T00:00:00.000Z,
"lte": 1999-09-09T23:59:59.000Z,
"lte": 1999-09-09T23:59:59.999Z,
},
},
}
Expand All @@ -140,7 +151,7 @@ describe('dateQuery', () => {
Object {
"range": Object {
"birthDate": Object {
"gt": 1999-09-09T23:59:59.000Z,
"gt": 1999-09-09T23:59:59.999Z,
},
},
},
Expand All @@ -161,7 +172,7 @@ describe('dateQuery', () => {
Object {
"range": Object {
"birthDate": Object {
"lt": 1999-09-09T23:59:59.000Z,
"lt": 1999-09-09T23:59:59.999Z,
},
},
}
Expand All @@ -172,7 +183,7 @@ describe('dateQuery', () => {
Object {
"range": Object {
"birthDate": Object {
"lte": 1999-09-09T23:59:59.000Z,
"lte": 1999-09-09T23:59:59.999Z,
},
},
}
Expand Down Expand Up @@ -205,7 +216,7 @@ describe('dateQuery', () => {
Object {
"range": Object {
"birthDate": Object {
"gt": 1999-09-09T23:59:59.000Z,
"gt": 1999-09-09T23:59:59.999Z,
},
},
}
Expand Down
12 changes: 7 additions & 5 deletions src/QueryBuilder/typeQueries/dateQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ interface DateSearchParameter {

// The date parameter format is yyyy-mm-ddThh:mm:ss[Z|(+|-)hh:mm] (the standard XML format).
// https://www.hl7.org/fhir/search.html#date
const DATE_SEARCH_PARAM_REGEX = /^(?<prefix>eq|ne|lt|gt|ge|le|sa|eb|ap)?(?<inputDate>(?<year>\d{4})(?:-(?<month>\d{2})(?:-(?<day>\d{2})(?:T(?<hours>\d{2}):(?<minutes>\d{2})(?::(?<seconds>\d{2})(?<timeZone>Z|[+-](?:\d{2}:\d{2}))?)?)?)?)?)$/;
const DATE_SEARCH_PARAM_REGEX = /^(?<prefix>eq|ne|lt|gt|ge|le|sa|eb|ap)?(?<inputDate>(?<year>\d{4})(?:-(?<month>\d{2})(?:-(?<day>\d{2})(?:T(?<hours>\d{2}):(?<minutes>\d{2})(?::(?<seconds>\d{2})(?:\.(?<milliseconds>\d{3}))?(?<timeZone>Z|[+-](?:\d{2}:\d{2}))?)?)?)?)?)$/;

export const parseDateSearchParam = (param: string): DateSearchParameter => {
const match = param.match(DATE_SEARCH_PARAM_REGEX);
if (match === null) {
throw new InvalidSearchParameterError(`Invalid date search parameter: ${param}`);
}
const { inputDate, month, day, minutes, seconds } = match.groups!;
const { inputDate, month, day, minutes, seconds, milliseconds } = match.groups!;

// If no prefix is present, the prefix eq is assumed.
// https://www.hl7.org/fhir/search.html#prefix
Expand All @@ -42,11 +42,13 @@ export const parseDateSearchParam = (param: string): DateSearchParameter => {
// When the date parameter is not fully specified, matches against it are based on the behavior of intervals
// https://www.hl7.org/fhir/search.html#date
let endDate: Date;
const timeEndOfDay = { hours: 23, minutes: 59, seconds: 59 };
if (seconds !== undefined) {
const timeEndOfDay = { hours: 23, minutes: 59, seconds: 59, milliseconds: 999 };
if (milliseconds !== undefined) {
endDate = parsedDate; // date is fully specified
} else if (seconds !== undefined) {
endDate = set(parsedDate, { milliseconds: 999 });
} else if (minutes !== undefined) {
endDate = set(parsedDate, { seconds: 59 });
endDate = set(parsedDate, { seconds: 59, milliseconds: 999 });
} else if (day !== undefined) {
endDate = set(parsedDate, timeEndOfDay);
} else if (month !== undefined) {
Expand Down

0 comments on commit 86dbccd

Please sign in to comment.