Skip to content

Commit

Permalink
Fixed issue with identifying invalid timezone format (deephaven#2091)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Jun 25, 2024
1 parent 6bc514b commit 5f949ed
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 9 deletions.
59 changes: 56 additions & 3 deletions packages/jsapi-utils/src/DateUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,37 @@ describe('dateTimeString parsing tests', () => {
);
});

it('handles YYYY-xxx', () => {
testDateTimeString('2012-mar', {
year: '2012',
month: 'mar',
});

testDateTimeString('2012-march', {
year: '2012',
month: 'march',
});
});

it('handles YYYY-m-d', () => {
testDateTimeString('2012-4-6', {
year: '2012',
month: '4',
date: '6',
});

testDateTimeString(
'2012-04-20 overflow',
{
year: '2012',
month: '04',
date: '20',
overflow: ' overflow',
},
true
);
});

it('handles YYYY-mm-dd', () => {
testDateTimeString('2012-04-20', {
year: '2012',
Expand Down Expand Up @@ -304,6 +335,7 @@ describe('dateTimeString parsing tests', () => {

it('throws an error for invalid dates', () => {
testDateTimeStringThrows('not a date');
testDateTimeStringThrows('2013-231-04');
testDateTimeStringThrows('20133-23-04');
testDateTimeStringThrows('2013-23-043');
testDateTimeStringThrows('2013-23-34zzz');
Expand Down Expand Up @@ -449,7 +481,7 @@ describe('getJsDate', () => {
});
});

describe('trimDateTimeStringOverflow', () => {
describe('trimDateTimeStringTimeZone', () => {
const dateTimeTexts = [
'2024',
'2012-04',
Expand All @@ -463,7 +495,7 @@ describe('trimDateTimeStringOverflow', () => {
it.each(dateTimeTexts)(
'should return given string if no overflow: %s',
given => {
const actual = DateUtils.trimDateTimeStringOverflow(given);
const actual = DateUtils.trimDateTimeStringTimeZone(given);
expect(actual).toEqual(given);
}
);
Expand All @@ -472,8 +504,29 @@ describe('trimDateTimeStringOverflow', () => {
'should trim date time string overflow: %s',
expected => {
const given = `${expected} overflow`;
const actual = DateUtils.trimDateTimeStringOverflow(given);
const actual = DateUtils.trimDateTimeStringTimeZone(given);
expect(actual).toEqual(expected);
}
);

it.each([
'2024overflow',
'2012-04overflow',
'2012-04-20overflow',
'2012-04-20T12overflow',
'2012-04-20T12:13overflow',
'2012-04-20T12:13:14overflow',
'2012-04-20T12:13:14.321overflow',
'2024overflow',
'2012-04 overflow',
'2012-04-20 overflow',
'2012-04-20T12 overflow',
'2012-04-20T12:13 overflow',
'2012-04-20T12:13:14 overflow',
'2012-04-20T12:13:14.321 overflow',
])('should throw for invalid timezone overflow: %s', invalidOverflow => {
expect(() => DateUtils.trimDateTimeStringTimeZone(invalidOverflow)).toThrow(
`Unexpected timezone format in overflow: '${invalidOverflow}'`
);
});
});
13 changes: 11 additions & 2 deletions packages/jsapi-utils/src/DateUtils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { dh as DhType } from '@deephaven/jsapi-types';

const DATE_TIME_REGEX =
/\s*(\d{4})([-./]([\da-z]+))?([-./](\d{1,2}))?([tT\s](\d{2})([:](\d{2}))?([:](\d{2}))?([.](\d{1,9}))?)?(.*)/;
/\s*(\d{4})([-./](\d{1,2}|[a-z]+))?([-./](\d{1,2}))?([tT\s](\d{2})([:](\d{2}))?([:](\d{2}))?([.](\d{1,9}))?)?(.*)/;

interface DateParts<T> {
year: T;
Expand Down Expand Up @@ -247,6 +247,7 @@ export class DateUtils {
nanos,
overflow,
] = result;

if (!allowOverflow && overflow != null && overflow.length > 0) {
throw new Error(
`Unexpected characters after date string '${dateTimeString}': ${overflow}`
Expand Down Expand Up @@ -388,7 +389,7 @@ export class DateUtils {
* @param dateTimeString The date time string to trim
* @returns The date time string without overflow
*/
static trimDateTimeStringOverflow(dateTimeString: string): string {
static trimDateTimeStringTimeZone(dateTimeString: string): string {
const { overflow = '' } = DateUtils.parseDateTimeString(
dateTimeString,
true
Expand All @@ -398,6 +399,14 @@ export class DateUtils {
return dateTimeString;
}

// Expecting timezone overflow to be a single space followed by some
// combination of letters
if (!/^\s[A-Za-z]+/.test(overflow)) {
throw new Error(
`Unexpected timezone format in overflow: '${dateTimeString}'`
);
}

return dateTimeString.slice(0, -overflow.length);
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/jsapi-utils/src/TableUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ describe('makeFilterValue', () => {
const value = '2023-12-21';
mockTableUtils.makeFilterValue(columnType, value);
expect(mockDh.FilterValue.ofNumber).toHaveBeenCalledWith(
DateUtils.trimDateTimeStringOverflow(value)
DateUtils.trimDateTimeStringTimeZone(value)
);
});

Expand Down Expand Up @@ -773,7 +773,7 @@ describe('makeSearchTextFilter', () => {
mockTableUtils.makeQuickDateFilterWithOperation
).toHaveBeenCalledWith(
dateColumn,
DateUtils.trimDateTimeStringOverflow(searchText),
DateUtils.trimDateTimeStringTimeZone(searchText),
'eq',
mockTimeZone
);
Expand Down
4 changes: 2 additions & 2 deletions packages/jsapi-utils/src/TableUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ export class TableUtils {
if (valueType === this.dh.ValueType.DATETIME) {
return this.makeQuickDateFilterWithOperation(
column,
DateUtils.trimDateTimeStringOverflow(searchText),
DateUtils.trimDateTimeStringTimeZone(searchText),
'eq',
timeZone
);
Expand Down Expand Up @@ -1889,7 +1889,7 @@ export class TableUtils {
}
if (TableUtils.isDateType(type)) {
return dh.FilterValue.ofNumber(
DateUtils.trimDateTimeStringOverflow(value) as unknown as number
DateUtils.trimDateTimeStringTimeZone(value) as unknown as number
);
}

Expand Down

0 comments on commit 5f949ed

Please sign in to comment.