2

I use MdDatePickerModule to pick dates but I have a problem: If I select August 5, everything is ok. But if I reopen the selection the month changes and becomes May, if I select May 3, I close, re-open, the month is March. Now I know that the problem is that in America the month and the day are inverted compared to Europe, but what is the "smart" way to resolve the conflict. thanks

Nehal
  • 13,130
  • 4
  • 43
  • 59

2 Answers2

4

The correct way of doing it for now is to set the locale as well as having a custom adapter to parse the date properly.

ts:

import {Component} from '@angular/core';
import { NativeDateAdapter, DateAdapter, MD_DATE_FORMATS } from "@angular/material";

export class ItalianDateAdapter extends NativeDateAdapter {
  parse(value: any): Date | null {
    if ((typeof value === 'string') && (value.indexOf('/') > -1)) {
      const str = value.split('/');
      if (str.length < 2 || isNaN(+str[0]) || isNaN(+str[1]) || isNaN(+str[2])) {
        return null;
      }
      return new Date(Number(str[2]), Number(str[1]) - 1, Number(str[0]), 12);
    }
    const timestamp = typeof value === 'number' ? value : Date.parse(value);
    return isNaN(timestamp) ? null : new Date(timestamp);
  }
}

@Component({
  selector: 'datepicker-overview-example',
  templateUrl: './datepicker-overview-example.html',
  styleUrls: ['./datepicker-overview-example.css'],
  providers: [{provide: DateAdapter, useClass: ItalianDateAdapter}],
})
export class DatepickerOverviewExample {

  locale: string;

  constructor(private dateAdapter: DateAdapter<Date>) {
    this.locale = 'it';
    this.dateAdapter.setLocale('it');   
  }

}

Plunker demo

This bug has been reported to Material team and being tracked by the following issue.

Nehal
  • 13,130
  • 4
  • 43
  • 59
  • Thanks for your answer, (tried 'en-gb' and also 'it') but I have the same problem with both my code and your plunkers. – Antonino Mirabile Aug 05 '17 at 20:36
  • Can you fork the plunker, re-create your problem, and share the link? – Nehal Aug 05 '17 at 20:39
  • 1
    I have the same problem with your plunker. If I select a day below 12, at the next reopening for the date selection the month changes according to the selected day: I select today August 5, I choose again and the month is May 2017, I select May 4, again open to choose another date and the month is April 2017 and so on. If I pick 13 or over the month it's back to August. I am Italian, here is dd / mm / yyyy. I do not change a comma to your plunkers and I always have the same problem. – Antonino Mirabile Aug 05 '17 at 21:03
  • Ohh, I see the problem now. I work on it, thank you! – Nehal Aug 05 '17 at 21:07
  • @AntoninoMirabile, try the updated answer. I am sorry for not verifying the previous answer before posting it. – Nehal Aug 05 '17 at 23:16
  • one exta point here: DateAdapter need to be imported to all modules. not only main. – dimson d Aug 06 '21 at 12:28
2

I was struggling with similar problem. In my app I want to use both 'en' and 'pl' date formats. All I did was adding second if() in parse method. So my adapter looks like this now:

export class MyDateAdapter extends NativeDateAdapter {


  // change first day of the week to Monday(1)
  getFirstDayOfWeek(): number {
    return 1;
  }

  parse(value: any): Date | null {

    // english format
    if ((typeof value === 'string') && (value.indexOf('/') > -1)) {
      const str = value.split('/');
      if (str.length < 2 || isNaN(+str[0]) || isNaN(+str[1]) || isNaN(+str[2])) {
        return null;
      }
      return new Date(Number(str[2]), Number(str[0]) - 1, Number(str[1]), 12);
    }

    // polish format
    if ((typeof value === 'string') && (value.indexOf('.') > -1)) {
      const str = value.split('.');
      if (str.length < 2 || isNaN(+str[0]) || isNaN(+str[1]) || isNaN(+str[2])) {
        return null;
      }

      return new Date(Number(str[2]), Number(str[1]) - 1, Number(str[0]), 12);
    }

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

 }