Search code examples
angularangular-material

Why is My Custom Date Format Not Working in Angular Material Datepicker and How Can I Fix It?


To change the date format in the Material datepicker, I added the following configuration:

export const MY_DATE_FORMATS = {
  parse: {
    dateInput: 'DD/MM/YYYY',
  },
  display: {
    dateInput: 'DD/MM/YYYY',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'DD/MM/YYYY',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};

and included it in the providers:

{ provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS },

However, the date format still displays as MM/DD/YYYY.

Why is this happening and how can I fix it?

Check out the implementation here: StackBlitz.


Solution

  • First we should install @angular/material-moment-adapter

    npm i @angular/material-moment-adapter
    

    I am able to get it working by using the below import

    import { provideMomentDateAdapter } from '@angular/material-moment-adapter';
    

    Then we just need to add it to the providers array like so

    @Component({
      selector: 'datepicker-overview-example',
      templateUrl: 'datepicker-overview-example.html',
      standalone: true,
      providers: [provideMomentDateAdapter(MY_DATE_FORMATS)],
      imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule],
    })
    export class DatepickerOverviewExample {}
    

    FULL CODE:

    import {Component} from '@angular/core';
    import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
    import {provideMomentDateAdapter} from '@angular/material-moment-adapter';
    
    // Depending on whether rollup is used, moment needs to be imported differently.
    // Since Moment.js doesn't have a default export, we normally need to import using the `* as`
    // syntax. However, rollup creates a synthetic default module and we thus need to import it using
    // the `default as` syntax.
    import * as _moment from 'moment';
    // tslint:disable-next-line:no-duplicate-imports
    import {default as _rollupMoment} from 'moment';
    import {MatDatepickerModule} from '@angular/material/datepicker';
    import {MatInputModule} from '@angular/material/input';
    import {MatFormFieldModule} from '@angular/material/form-field';
    
    const moment = _rollupMoment || _moment;
    
    // See the Moment.js docs for the meaning of these formats:
    // https://momentjs.com/docs/#/displaying/format/
    export const MY_FORMATS = {
      parse: {
        dateInput: 'LL',
      },
      display: {
        dateInput: 'LL',
        monthYearLabel: 'MMM YYYY',
        dateA11yLabel: 'LL',
        monthYearA11yLabel: 'MMMM YYYY',
      },
    };
    
    /** @title Datepicker with custom formats */
    @Component({
      selector: 'datepicker-formats-example',
      templateUrl: 'datepicker-formats-example.html',
      providers: [
        // Moment can be provided globally to your app by adding `provideMomentDateAdapter`
        // to your app config. We provide it at the component level here, due to limitations
        // of our example generation script.
        provideMomentDateAdapter(MY_FORMATS),
      ],
      standalone: true,
      imports: [
        MatFormFieldModule,
        MatInputModule,
        MatDatepickerModule,
        FormsModule,
        ReactiveFormsModule,
      ],
    })
    export class DatepickerFormatsExample {
      date = new FormControl(moment());
    }
    

    Stackblitz Demo