10
votes

ive set the locale of the date to be en-GB - so that the datepicker can be in the UK format.

If i enter a date manually 10/12/2018 (10th December 2018) and hit tab the date gets converted to 12/10/2018 (12th October 2018) .

Selecting the original date using the picker works fine this problem only occurs when typing it in manually and when specifying a locale.

https://stackblitz.com/edit/angular-hv6jny

<mat-form-field>
  <input matInput [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

--

  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
  ]

Is this a bug with the datepicker?

2

2 Answers

9
votes

It's not a bug. You need to build a custom date adapter like this:

export class CustomDateAdapter extends NativeDateAdapter {

    parse(value: any): Date | null {

    if ((typeof value === 'string') && (value.indexOf('/') > -1)) {
       const str = value.split('/');

      const year = Number(str[2]);
      const month = Number(str[1]) - 1;
      const date = Number(str[0]);

      return new Date(year, month, date);
    }
    const timestamp = typeof value === 'number' ? value : Date.parse(value);
    return isNaN(timestamp) ? null : new Date(timestamp);
  }

  format(date: Date, displayFormat: Object): string {
    date = new Date(Date.UTC(
      date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(),
      date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
    displayFormat = Object.assign({}, displayFormat, { timeZone: 'utc' });

    const dtf = new Intl.DateTimeFormat(this.locale, displayFormat);
    return dtf.format(date).replace(/[\u200e\u200f]/g, '');
  }

}

and then use it in your app:

@NgModule({
    ....
    provide: DateAdapter, useClass: CustomDateAdapter }
})

DEMO

0
votes

To support other locales, that use dots in stead of slashes, you can also use the moment dateadapter and formats. Moment supports this functionality out of the box.

npm install moment @angular/material-moment-adapter --save

app.module.ts

  providers: [
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE]
    },
    {
      provide: MAT_DATE_FORMATS,
      useValue: MAT_MOMENT_DATE_FORMATS
    }
  ],