What do I want to achieve?
I want my Angular Material(v11) datepicker to use the DD-MM-YYYY format in an Angular version 11 project.
What have I tried?
I tried using the MatMomentDateModule
but this uses the moment.js library. This in turn will use all the locales in the bundle, which inceases the bundle size with 400kb. I have added CUSTOM_DATE_FORMATS
to the providers of my app.module.ts
which looks like this:
const CUSTOM_DATE_FORMATS = {
parse: {
dateInput: 'DD-MM-YYYY',
},
display: {
dateInput: 'DD-MM-YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
And this works but as mentioned before, the bundle size increases severely and i don't use any locales.
Is there a way to do format my date DD-MM-YYYY, without the use of the moment.js library?
or
Is the moment.js treeshakable in a way so that i only use the stuff that i need?
mat-datepicker exampleAdd a template reference variable mat-datepicker element. Connect mat-datepicker to input element via [matDatepicker] property. Finally add date picker toggle button to display or hide calender popup by using mat-datepicker-toggle element.
Connecting a datepicker to an input A datepicker is composed of a text input and a calendar pop-up, connected via the matDatepicker property on the text input. There is also an optional datepicker toggle button that gives the user an easy way to open the datepicker pop-up.
So i didn't knew if you used the MatNativeDateModule
that you could also implement a custom date adapter. I thought this was something that was specific to MatMomentDateModule
.
Once I figured this out i could just overwrite the format function and format it manually likes so:
export class CustomDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: any): string {
const days = date.getDate();
const months = date.getMonth() + 1;
const year = date.getFullYear();
return days + '-' + months + '-' + year;
}
}
And implement it like so:
@NgModule({
providers: [
{
provide: DateAdapter,
useClass: AppDateAdapter,
deps: [MAT_DATE_LOCALE, Platform]
},
]
})
export class AppModule { }
Found this solution here and it works as intended https://www.angularjswiki.com/material/datepicker/#mat-datepicker-date-format
import { NativeDateAdapter, DateAdapter,MAT_DATE_FORMATS } from '@angular/material';
import { formatDate } from '@angular/common';
export const PICK_FORMATS = {
parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
display: {
dateInput: 'input',
monthYearLabel: {year: 'numeric', month: 'short'},
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'}
}
};
class PickDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
return formatDate(date,'dd-MMM-yyyy',this.locale);;
} else {
return date.toDateString();
}
}
}
And then just use it in your module or component providers
providers: [
{provide: DateAdapter, useClass: PickDateAdapter},
{provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
]
Had the same issue myself today and did not want to use moment.js.
It seems if you only want a standard date format (e.g. non-US) a simple solution is to add to your app.module.ts:
import { MAT_DATE_LOCALE } from '@angular/material/core';
@NgModule({
...
providers: [{provide: MAT_DATE_LOCALE, useValue: 'en-GB'}],
...
No doubt other country codes would also work. This approach presumably changes all date appearances across your application (not just your datepicker) but in my case this was perfectly acceptable. No further changes were required in the component nor HTML template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With