date-formatting-fix (#1746)

* use a regex to determine if a date is potentially valid

* added test back in

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-06-17 14:37:01 -04:00 committed by jasquat
parent 10b30f6c14
commit 238335bcb3
No known key found for this signature in database
3 changed files with 60 additions and 4 deletions

View File

@ -80,6 +80,7 @@ const PROCESS_STATUSES = [
// with time: yyyy-MM-dd HH:mm:ss
let generalDateFormat = 'yyyy-MM-dd';
// let generalDateFormat = 'dd-MMM-yyyy';
if (
'spiffworkflowFrontendJsenv' in window &&
'DATE_FORMAT' in window.spiffworkflowFrontendJsenv

View File

@ -1,5 +1,42 @@
import DateAndTimeService from './DateAndTimeService';
test('it can tell if a string looks like a date', () => {
const validDates = [
'2024-06-01',
'14-06-2024',
'1-06-2024',
'14-6-2024',
'14-Jun-2024',
'14-March-2024',
'March 4, 2024',
'4 March 2024',
'04/03/2024',
'04.03.2024',
];
validDates.forEach((dateString: string) => {
try {
expect(DateAndTimeService.stringLooksLikeADate(dateString)).toBe(true);
} catch (exception) {
throw Error(`Date failed: ${dateString}: ${exception}`);
}
});
const invalidDates = [
'2024-06-0',
'2024-6-01',
'14-06-202',
'14-Jun-202',
'14#06#20204',
];
invalidDates.forEach((dateString: string) => {
try {
expect(DateAndTimeService.stringLooksLikeADate(dateString)).toBe(false);
} catch (exception) {
throw Error(`Date failed: ${dateString}: ${exception}`);
}
});
});
test('it can keep the correct date when converting seconds to date', () => {
const dateString =
DateAndTimeService.convertSecondsToFormattedDateString(1666325400);
@ -25,6 +62,7 @@ test('it can properly format a duration', () => {
test('it can get the correct date format from string', () => {
const expectedDateString = '2024-03-04';
const newDateFormat = 'dd-MMM-yyyy';
const marchDate = 'March 4, 2024';
expect(
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
@ -38,7 +76,7 @@ test('it can get the correct date format from string', () => {
).toEqual(expectedDateString);
expect(
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
'March 4, 2024',
marchDate,
),
).toEqual(expectedDateString);
expect(
@ -65,7 +103,7 @@ test('it can get the correct date format from string', () => {
).toEqual(expectedDateString);
expect(
DateAndTimeService.attemptToConvertUnknownDateStringFormatToKnownFormat(
'March 4, 2024',
marchDate,
newDateFormat,
),
).toEqual(expectedDateString);

View File

@ -14,6 +14,18 @@ const FOUR_HOURS_IN_SECONDS = SECONDS_IN_HOUR * 4;
const REFRESH_INTERVAL_SECONDS = 5;
const REFRESH_TIMEOUT_SECONDS = FOUR_HOURS_IN_SECONDS;
const stringLooksLikeADate = (dateString: string): boolean => {
// We had been useing date-fns parse to really check if a date is valid however it attempts to parse dates like 14-06-2 because it thinks it is 14-06-0002.
// This results in a validate date but has a negative time with getTime which is a valid number however we do not want dates like this at all.
// Checking for negative numbers seem wrong so use a regex to see if it looks anything like a date.
return (
(dateString.match(/^\d{4}[-/.]\d{2}[-/.]\d{2}$/) ||
dateString.match(/^(\d{1,2}|\w+)[-/.](\d{1,2}|\w+)[-/.]\d{4}$/) ||
dateString.match(/^\w+ +\d+, +\d{4}$/) ||
dateString.match(/^\d+ +\w+ +\d{4}$/)) !== null
);
};
const convertDateToSeconds = (date: any, onChangeFunction: any = null) => {
let dateInSeconds = date;
if (date !== null) {
@ -44,7 +56,11 @@ const dateStringToYMDFormat = (dateString: string) => {
if (dateString === undefined || dateString === null) {
return dateString;
}
if (dateString && dateString.match(/^\d{4}-\d{2}-\d{2}$/)) {
if (
dateString.match(/^\d{4}-\d{2}-\d{2}$/) ||
!stringLooksLikeADate(dateString)
) {
return dateString;
}
const newDate = parse(dateString, DATE_FORMAT, new Date());
@ -160,7 +176,7 @@ const attemptToConvertUnknownDateStringFormatToKnownFormat = (
}
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 (stringLooksLikeADate(dateString) && !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
@ -252,6 +268,7 @@ const DateAndTimeService = {
formatDateTime,
formatDurationForDisplay,
secondsToDuration,
stringLooksLikeADate,
ymdDateStringToConfiguredFormat,
};