Date format fixer (#1319)
* attmept to figure out what date format the user is inputting w/ burnettk * reverted default date config w/ burnettk * added tests for the new date formatter function * fixed outdated comment --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
cef93033e8
commit
b507f45fb0
|
@ -6,10 +6,15 @@ import {
|
|||
StrictRJSFSchema,
|
||||
WidgetProps,
|
||||
} from '@rjsf/utils';
|
||||
import { parse } from 'date-fns';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { DATE_FORMAT_CARBON, DATE_FORMAT_FOR_DISPLAY } from '../../../config';
|
||||
import {
|
||||
DATE_FORMAT,
|
||||
DATE_FORMAT_CARBON,
|
||||
DATE_FORMAT_FOR_DISPLAY,
|
||||
} from '../../../config';
|
||||
import DateAndTimeService from '../../../services/DateAndTimeService';
|
||||
import { getCommonAttributes } from '../../helpers';
|
||||
|
||||
|
@ -73,8 +78,12 @@ export default function BaseInputTemplate<
|
|||
);
|
||||
|
||||
const addDebouncedOnChangeDate = useDebouncedCallback(
|
||||
(target: React.ChangeEvent<HTMLInputElement>) => {
|
||||
_onChange(target);
|
||||
(fullObject: React.ChangeEvent<HTMLInputElement>) => {
|
||||
fullObject.target.value =
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
fullObject.target.value
|
||||
);
|
||||
_onChange(fullObject);
|
||||
},
|
||||
// delay in ms
|
||||
1000
|
||||
|
@ -93,6 +102,8 @@ export default function BaseInputTemplate<
|
|||
// it should in be y-m-d when it gets here.
|
||||
let dateValue: string | null = value;
|
||||
if (value || value === 0) {
|
||||
// it would be good if we could compare against the length of the desired format but that doesn't work in all cases and causes some issues.
|
||||
// 10 seems to be a good value check against.
|
||||
if (value.length < 10) {
|
||||
dateValue = value;
|
||||
} else {
|
||||
|
|
|
@ -5,6 +5,7 @@ test('it can keep the correct date when converting seconds to date', () => {
|
|||
DateAndTimeService.convertSecondsToFormattedDateString(1666325400);
|
||||
expect(dateString).toEqual('2022-10-21');
|
||||
});
|
||||
|
||||
test('it can properly format a duration', () => {
|
||||
expect(DateAndTimeService.formatDurationForDisplay('0')).toEqual('0s');
|
||||
expect(DateAndTimeService.formatDurationForDisplay('60')).toEqual('1m');
|
||||
|
@ -20,3 +21,82 @@ test('it can properly format a duration', () => {
|
|||
'365d 12m 45s'
|
||||
);
|
||||
});
|
||||
|
||||
test('it can get the correct date format from string', () => {
|
||||
const expectedDateString = '2024-03-04';
|
||||
const newDateFormat = 'dd-MMM-yyyy';
|
||||
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
expectedDateString
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'03-04-2024'
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'March 4, 2024'
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'mar-4-2024'
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'03/04/2024'
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'03.04.2024'
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'04-03-2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'March 4, 2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'4-mar-2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'4 March 2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'04/03/2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
'04.03.2024',
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
expect(
|
||||
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
|
||||
expectedDateString,
|
||||
newDateFormat
|
||||
)
|
||||
).toEqual(expectedDateString);
|
||||
});
|
||||
|
|
|
@ -147,6 +147,46 @@ const secondsToDuration = (secNum: number) => {
|
|||
return duration;
|
||||
};
|
||||
|
||||
const attemptToConvertUnknownDateStringFormatToKnownFormat = (
|
||||
dateString: string,
|
||||
targetDateFormat?: string
|
||||
) => {
|
||||
let dateFormat = targetDateFormat;
|
||||
if (!dateFormat) {
|
||||
dateFormat = DATE_FORMAT;
|
||||
}
|
||||
let newDateString = dateString;
|
||||
// if the date starts with 4 digits then assume in y-m-d format and avoid all of this
|
||||
if (dateString.length >= 10 && !dateString.match(/^\d{4}/)) {
|
||||
// if the date format should contain month names or abbreviations but does not have letters
|
||||
// then attempt to parse in the same format but with digit months instead of letters
|
||||
|
||||
if (!dateString.match(/[a-zA-Z]+/) && dateFormat.match(/MMM/)) {
|
||||
const numericalDateFormat = dateFormat.replaceAll(/MMM*/g, 'MM');
|
||||
const dateFormatRegex = new RegExp(
|
||||
numericalDateFormat
|
||||
.replace('dd', '\\d{2}')
|
||||
.replace('MM', '\\d{2}')
|
||||
.replace('yyyy', '\\d{4}')
|
||||
);
|
||||
const normalizedDateString = dateString.replaceAll(/[.-/]+/g, '-');
|
||||
if (normalizedDateString.match(dateFormatRegex)) {
|
||||
const newDate = parse(
|
||||
normalizedDateString,
|
||||
dateFormat.replaceAll(/MMM*/g, 'MM'),
|
||||
new Date()
|
||||
);
|
||||
newDateString = convertDateObjectToFormattedString(newDate) || '';
|
||||
}
|
||||
} else {
|
||||
// NOTE: do not run Date.parse with y-m-d formats since it returns dates in a different timezone from other formats
|
||||
const newDate = new Date(Date.parse(`${dateString}`));
|
||||
newDateString = convertDateObjectToFormattedString(newDate) || '';
|
||||
}
|
||||
}
|
||||
return newDateString;
|
||||
};
|
||||
|
||||
const formatDurationForDisplay = (value: any) => {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
|
@ -193,6 +233,7 @@ const DateAndTimeService = {
|
|||
REFRESH_INTERVAL_SECONDS,
|
||||
REFRESH_TIMEOUT_SECONDS,
|
||||
|
||||
attemptToConvertUnknownDateStringFormatToKnownFormat,
|
||||
convertDateAndTimeStringsToDate,
|
||||
convertDateAndTimeStringsToSeconds,
|
||||
convertDateObjectToFormattedHoursMinutes,
|
||||
|
|
Loading…
Reference in New Issue