How can I use the Date-Fns Adapter for Angular Material to parse short date formats without an explicit separator? For example, 010123
=> 01.01.2023
. With the whole year it works as expected: 01012023
=> 01.01.2023
My actual thought process would be ddMMyy
but according to the Unicode Documentation:
However, "yy" requests just the two low-order digits of the year, zero-padded as necessary.
So the Unicode tokens would reference the year 0023
instead of 2023
.
My question is how can I adjust this context to get this desired behavior?
Here is my CUSTOM_FORMAT
:
export const CUSTOM_FORMAT: MatDateFormats = {
parse: {
dateInput: ["dd.MM.yyyy", "dd/MM/yyyy", "dd,MM,yyyy", "ddMMyyyy", "ddMMyy"],
},
display: {
dateInput: "dd.MM.yyyy",
monthYearLabel: "MMM yyyy",
dateA11yLabel: "MMMM d, y",
monthYearA11yLabel: "MMM yyyy"
},
};
I fixed my problem by writing a CustomDateAdapter that overrides the default parse function of the DateFnsAdapter.
In my CustomDateAdapter:
override parse(value: any, parseFormat: string | string[]): Date | null {
if (typeof value === 'string' && value.length > 0) {
if (!parseFormat.length) {
throw Error('Formats array must not be empty.');
}
// Check if the input value is in the format "ddMMyy" or "d.M.yy" or "dd.MM.yy"
const matchWithSeparator: RegExpMatchArray = value.match(/^(\d{1,2})[.\-/](\d{1,2})[.\-/](\d{2})$/);
const matchWithoutSeparator: RegExpMatchArray = value.match(/^(\d{2})(\d{2})(\d{2})$/);
// Gets first two digits of current year
const firstTwoDigitsOfCurrentYear: string = new Date().getFullYear().toString().slice(0,2);
// Convert the matched parts to a valid date string "DD.MM.YYYY"
if (matchWithSeparator) {
value = `${matchWithSeparator[1]}.${matchWithSeparator[2]}.${firstTwoDigitsOfCurrentYear}${matchWithSeparator[3]}`;
} else if (matchWithoutSeparator) {
value = `${matchWithoutSeparator[1]}.${matchWithoutSeparator[2]}.${firstTwoDigitsOfCurrentYear}${matchWithoutSeparator[3]}`;
}
// General parsing logic for multiple formats declared in shared.module
for (const currentFormat of parseFormat) {
const fromFormat: Date = parse(value, currentFormat, new Date(), { locale: this.locale });
if (this.isValid(fromFormat)) {
return fromFormat;
}
}
return this.invalid();
} else if (typeof value === 'number') {
return new Date(value);
} else if (value instanceof Date) {
return this.clone(value);
}
return null;
}