2

I'm new to Angular and I just jumped into an existing project. My issue is about a date picker from angular material. If I select a date via the toggle, no issue, the date is correct but if I want to put a date manually (format used : dd/MM/yyyy), it automatically switch dd and MM as I focus out the input field.

So for example, If I type : "07/04/2019", then I click on the next input I want to change, the date changes to "04/07/2019".

Here is the Input :

<mat-form-field>
    <input matInput [matDatepicker]="availableFrom" placeholder="From" formControlName="availableFrom" (dateChange)="fromDateLessThanToDate()">
    <mat-datepicker-toggle matSuffix [for]="availableFrom"></mat-datepicker-toggle>
    <mat-datepicker #availableFrom></mat-datepicker>
</mat-form-field>

fromDateLessThanToDate() {
    if (DateUtils.fromDateLessThanToDate(this.conventionForm.value.availableFrom, this.conventionForm.value.availableTo))
      this.error_date = { isError: true, errorMessage: 'To date can\'t before From date' };
    else
      this.error_date = { isError: false, errorMessage: '' };
  }

When we arrive in fromDatLessThanToDate() function, the date (this.conventionForm.value.availableFrom) already has a wrong value (days and months switched). I already tested some solutions like this Angular Material mat-datepicker (change) event and format but the result is the same.

2 Answers 2

3

When I had this issue I created this working fix:

import { NativeDateAdapter } from '@angular/material';

export class CustomDateAdapter extends NativeDateAdapter {
  parse(value: any): Date | null {
    if (typeof value === 'string') {
      let str = null;
      if ((value.indexOf('/') > -1)) {
        str = value.split('/');
      } else if ((value.indexOf('-') > -1)) {
        str = value.split('-');
      } else if ((value.indexOf('.') > -1)) {
        str = value.split('.');
      }
      if (str === null) {
        return null;
      }
      const year = Number(str[2]);
      const month = Number(str[1]) - 1;
      const date = Number(str[0]);
      if (month > 11) {
        return new Date(year, date - 1, month + 1);
      }
      return new Date(year, month, date);
    }
    const timestamp = typeof value === 'number' ? value : Date.parse(value);
    return isNaN(timestamp) ? null : new Date(timestamp);
  }
}

This overrides the way the material datepicker parses the date and you have control over it. You can modify the parse method to perform any kind of parse you want.

Then you in your module add the following line in providers array:

import { DateAdapter } from '@angular/material';

@NgModule( {
    { provide: DateAdapter, useClass: CustomDateAdapter }
} )
Sign up to request clarification or add additional context in comments.

Comments

0

Answer from IvanSt helped me, I'm using date-fns here instead:

parse(value: any): Date | null {
   const date = parse(value, 'dd/MM/yyyy', new Date());
   return date;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.