question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DatePicker with MAT_DATE_LOCALE = en-GB parses incorrectly if the day is changed?

See original GitHub issue

Bug:

With DatePicker, in the NgModule, I have the following settings:

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

If I input a string like “10/12/2017”, the picker will has 12 Oct 2017 selected, instead of 10 Dec 2017 since en-GB should use DD/MM/YYYY.

Others features of the DatePicker are working fine.

What are the steps to reproduce?

In the plnkr example provided at https://material.angular.io/components/datepicker/overview, in main.ts, just add settings to NgModule:

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

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 4.4.4, Material: Beta 12.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:5
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

7reactions
aljabalicommented, Oct 21, 2017

+1 as Iuqeckr

6reactions
oleksandr-tkachcommented, Oct 31, 2017

I changed this moment date adapter a bit. This works for me:

import { DateAdapter, MatDateFormats } from '@angular/material';
import { isMoment, Moment } from 'moment';
import * as moment from 'moment';

export const MOMENT_DATE_FORMATS: MatDateFormats = {
  parse: {
    dateInput: 'D/MM/YYYY'
  },
  display: {
    dateInput: 'DD/MM/YYYY',
    monthYearLabel: 'MMMM Y',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM Y'
  }
};

const dateNames: string[] = [];
for (let date = 1; date <= 31; date++) {
  dateNames.push(String(date));
}

export class MomentDateAdapter extends DateAdapter<Moment> {

  private localeData = moment.localeData();

  getYear(date: Moment): number {
    return date.year();
  }

  getMonth(date: Moment): number {
    return date.month();
  }

  getDate(date: Moment): number {
    return date.date();
  }

  getDayOfWeek(date: Moment): number {
    return date.day();
  }

  getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
    switch (style) {
      case 'long':
        return this.localeData.months();
      case 'short':
        return this.localeData.monthsShort();
      case 'narrow':
        return this.localeData.monthsShort().map(month => month[0]);
    }
  }

  getDateNames(): string[] {
    return dateNames;
  }

  getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
    switch (style) {
      case 'long':
        return this.localeData.weekdays();
      case 'short':
        return this.localeData.weekdaysShort();
      case 'narrow':
        return this.localeData.weekdaysShort();
    }
  }

  getYearName(date: Moment): string {
    return String(date.year());
  }

  getFirstDayOfWeek(): number {
    return this.localeData.firstDayOfWeek();
  }

  getNumDaysInMonth(date: Moment): number {
    return date.daysInMonth();
  }

  clone(date: Moment): Moment {
    return date.clone();
  }

  createDate(year: number, month: number, date: number): Moment {
    return moment([year, month, date]);
  }

  today(): Moment {
    return moment();
  }

  parse(value: any, parseFormat: any): Moment {
    let m = moment(value, parseFormat, true);
    if (!m.isValid()) {
      m = moment(value);
    }
    if (m.isValid()) {
      return m;
    }
    return null;
  }

  format(date: Moment, displayFormat: any): string {
    if (date) {
      return date.format(displayFormat);
    }
    return '';
  }

  addCalendarYears(date: Moment, years: number): Moment {
    return date.clone().add(years, 'y');
  }

  addCalendarMonths(date: Moment, months: number): Moment {
    return date.clone().add(months, 'M');
  }

  addCalendarDays(date: Moment, days: number): Moment {
    return date.clone().add(days, 'd');
  }

  setLocale(locale: any): void {
    this.localeData = moment.localeData(locale);
  }

  compareDate(first: Moment, second: Moment): number {
    return first.diff(second, 'seconds', true);
  }

  sameDate(first: any | Moment, second: any | Moment): boolean {
    if (first == null) {
      return second == null;
    } else if (isMoment(first)) {
      return first.isSame(second);
    }
    return super.sameDate(first, second);
  }

  clampDate(date: Moment, min?: any | Moment, max?: any | Moment): Moment {
    if (min && date.isBefore(min)) {
      return min;
    } else if (max && date.isAfter(max)) {
      return max;
    }
    return date;
  }

  isValid(date: Moment): boolean {
    return date.isValid();
  };

  isDateInstance(obj: Object): boolean {
    return moment.isMoment(obj);
  };

  toIso8601(date: Moment): string {
    return date.format();
  };

  fromIso8601(iso8601String: string): Moment {
    return moment(iso8601String);
  };

}

And don’t forget to update main application module with providers:

{provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS},
{provide: DateAdapter, useClass: MomentDateAdapter}
Read more comments on GitHub >

github_iconTop Results From Across the Web

day incorrect in angular material datepicker - Stack Overflow
When a user type date in text box instead of choosing date with datepicker then his code does't work it reduce one day...
Read more >
Datepicker - Angular Material
The datepicker allows users to enter a date either through text input, or by choosing a date from the calendar. It is made...
Read more >
DateTime picker displays incorrect format for our region
The date picker always returns and displays as mm/dd/yyyy I have set DateTimeZone to local and I've set the regional setting in SharePoint...
Read more >
Angular Material Datepicker : Set Locale - ConcretePage.com
Set Locale in Application Module using MAT_DATE_LOCALE. The default locale of Datepicker is changed by overriding the value of MAT_DATE_LOCALE .
Read more >
day incorrect in angular material datepicker - iTecNote
Angular – day incorrect in angular material datepicker. angularangular-material2datepicker. When I select a date I see the correct date in the field but, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found