@navikt/ds-react
Version:
React components from the Norwegian Labour and Welfare Administration.
141 lines (124 loc) • 3.17 kB
text/typescript
import { Locale, isBefore, parse, sub } from "date-fns";
import { isValidDate } from "./check-dates";
export const INPUT_DATE_STRING_FORMAT_DATE = "dd.MM.yyyy";
export const INPUT_DATE_STRING_FORMAT_MONTH = "MMMM yyyy";
const ALLOWED_INPUT_FORMATS_DATE = [
INPUT_DATE_STRING_FORMAT_DATE,
"ddMMyyyy",
"dd/MM/yyyy",
"dd-MM-yyyy",
];
const ALLOWED_INPUT_FORMATS_MONTH = [
"M/yyyy",
"MM/yyyy",
"M-yyyy",
"MM-yyyy",
"MM.yyyy",
"MMyyyy",
INPUT_DATE_STRING_FORMAT_MONTH,
...ALLOWED_INPUT_FORMATS_DATE,
];
export const parseDate = (
date: string,
today: Date,
locale: Locale,
type: "date" | "month",
allowTwoDigitYear: boolean,
): Date => {
let parsed: Date;
const ALLOWED_FORMATS =
type === "date" ? ALLOWED_INPUT_FORMATS_DATE : ALLOWED_INPUT_FORMATS_MONTH;
if (allowTwoDigitYear) {
for (const format of ALLOWED_FORMATS) {
parsed = parse(date, format, today, { locale });
if (
isValidDate(parsed) &&
!isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
) {
return parsed;
}
}
for (const format of [
...ALLOWED_FORMATS.map((x) => x.replace("yyyy", "yy")),
]) {
parsed = parse(date, format, today, { locale });
if (
isValidDate(parsed) &&
isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
) {
const convertedDate = assignCenturyToDate(date, format, today, locale);
if (isValidDate(new Date(convertedDate))) {
return new Date(convertedDate);
}
return new Date("Invalid date");
}
}
return new Date("Invalid date");
}
for (const format of ALLOWED_FORMATS) {
parsed = parse(date, format, today, { locale });
if (
isValidDate(parsed) &&
!isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
) {
return parsed;
}
}
return new Date("Invalid date");
};
function isTwoDigitYear(
dateString: string,
today: Date,
locale: Locale,
formats: string[],
) {
let parsed: Date;
const newFormat = formats.map((x) => x.replace("yyyy", "yy"));
for (const format of newFormat) {
parsed = parse(dateString, format, today, { locale });
if (isValidDate(parsed)) {
return true;
}
}
return false;
}
function assignCenturyToDate(
dateStr: string,
format: string,
today: Date,
locale: Locale,
) {
const date20Century = parse(
appendCenturyToTwoYearDigitDateString(dateStr, "19"),
format.replace("yy", "yyyy"),
today,
{ locale },
);
const date21Century = parse(
appendCenturyToTwoYearDigitDateString(dateStr, "20"),
format.replace("yy", "yyyy"),
today,
{ locale },
);
if (isValidDate(date20Century) && isValidDate(date21Century)) {
return isBefore(
date20Century,
sub(new Date(), {
years: 80,
}),
)
? date21Century
: date20Century;
}
return new Date("Invalid date");
}
function appendCenturyToTwoYearDigitDateString(
dateString: string,
century: "19" | "20",
) {
const twoDigitYear = dateString.slice(-2);
return `${dateString.slice(
0,
dateString.length - 2,
)}${century}${twoDigitYear}`;
}