How to change the date format of Angular material date range picker?
Asked Answered
M

3

6

How to change the date format to a custom one in Angular materials date range picker?

E.g. for a another date format: DD/MM/YYYY

Basic date range picker:

    <mat-form-field appearance="fill">
      <mat-label>Enter a date range</mat-label>
      <mat-date-range-input [rangePicker]="picker">
        <input matStartDate placeholder="Start date">
        <input matEndDate placeholder="End date">
      </mat-date-range-input>
      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <mat-date-range-picker #picker></mat-date-range-picker>
    </mat-form-field>

Basic date range picker as Stackblitz.

Merrillmerrily answered 28/7, 2020 at 14:15 Comment(0)
D
8

It's pretty simple. First of all in your component import following.

import { NativeDateAdapter, MatDateFormats } from '@angular/material';
import {DateAdapter, MAT_DATE_FORMATS} from '@angular/material/core';

Now Create one class 'AppDateAdapter' which extends NativeDateAdapter. See following

export class AppDateAdapter extends NativeDateAdapter {
      format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
  let day: string = date.getDate().toString();
  day = +day < 10 ? '0' + day : day;
  let month: string = (date.getMonth() + 1).toString();
  month = +month < 10 ? '0' + month : month;
  let year = date.getFullYear();
  return `${day}-${month}-${year}`;
}
return date.toDateString();
}}

Create const APP_DATE_FORMATS

    export const APP_DATE_FORMATS: MatDateFormats = {
   parse: {
    dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
  },
  display: {
    dateInput: 'input',
    monthYearLabel: { year: 'numeric', month: 'numeric' },
    dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric'
    },
    monthYearA11yLabel: { year: 'numeric', month: 'long' },
  }
};

In your component add provider

@Component({
  selector: "app-home",
  templateUrl: "./home.component.html",
  styleUrls: ["./home.component.css"],
  providers: [
    {provide: DateAdapter, useClass: AppDateAdapter},
    {provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS}
  ]
})

Now whenever you change the date from datepicker than it will display in "dd-mm-yyyy" format because we have declared the format in AppDateAdapter. You can change that.

Degeneration answered 10/8, 2020 at 12:52 Comment(1)
Sooo simple :D :D Am I the only one feels Angular Material is a piece of junk? It has only one plus point which is cool look. But coding is a mess. Disgusting....Feudal
N
1

As per the official documents found here with a few minor tweaks: Found Here

Add the following to your app.module.ts / main module file imports section (View the display formats Here):

    import { MatNativeDateModule, DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS } from '@angular/material/core';
    import { MomentDateModule, MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';
        export const MY_FORMATS = {
          parse: {
            dateInput: 'LL',
          },
          display: {
            dateInput: 'LL',
            monthYearLabel: 'MMM YYYY',
            dateA11yLabel: 'LL',
            monthYearA11yLabel: 'MMMM YYYY',
          },
        };
    
        @NgModule({
          imports: [
        
          MatDatepickerModule,
          MatNativeDateModule,
          MomentDateModule,
        ],
        ....

Add the following to your providers section in your app.module.ts / main module

providers: [
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
    },

    {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
  ],

Make sure to install moment.js:

npm install moment --save

In your component import the following:

import * as moment from 'moment';

In your component (reactive forms) bind your input fields, note the moment(your_start_date):

this.theForm = this.formBuilder.group({
      startDate: [moment(this.service.filter.startDate), [Validators.required]],
      endDate: [moment(this.service.filter.endDate), [Validators.required]]
      })
    });

Add this to your Template

    <mat-form-field>
           <mat-label>Date Range</mat-label>
           <mat-date-range-input [rangePicker]="dateRangePicker" >
                <input matStartDate formControlName="startDate" placeholder="Start date">
                <input matEndDate formControlName="endDate" placeholder="End date">
           </mat-date-range-input>
           <mat-datepicker-toggle matSuffix [for]="dateRangePicker"></mat-datepicker-toggle>
           <mat-date-range-picker #dateRangePicker></mat-date-range-picker>
   </mat-form-field>
Neumeyer answered 10/8, 2020 at 12:26 Comment(5)
When I use your solution I got ERROR TypeError: date.getFullYear is not a function at NativeDateAdapter.getYear ...Rightly
As per your console, where is it giving you this error?Neumeyer
Also: What version of Angular and material are you on? mat-date-range-input doesn't work on Angular versions lower than 10.0.2 and materials version 10.1.2. To take advantage of this, you have to update your application, this is pretty straightforward if you are on version 9. I faced the same issue and after updating the range date picker is working. For detailed information of how to update go to: update.angular.io.Neumeyer
I had the same problem https://mcmap.net/q/1782071/-angular-material-10-range-datepicker-and-moment-js-error-date-getfullyear-is-not-a-function/1842159 and the answer https://mcmap.net/q/1782071/-angular-material-10-range-datepicker-and-moment-js-error-date-getfullyear-is-not-a-function works for meRightly
@Cichy, I do apologize, I forgot to add the "Imports" section. Hope this helps ..Neumeyer
P
0

you can use template literals to convert to short date format "YYYY-MM-DD" after receiving value from angular datepicker.

let due_date = this.form.get('due_Date').value

due_date = ${due_date._i.year}-${due_date._i.month + 1}-${due_date._i.date}

since you want "DD/MM/YYYY" then use

due_date = ${due_date._i.date}/${due_date._i.month + 1}/${due_date._i.year}

ignore the last ` tick as I don't how to remove in this editor

Pozsony answered 12/12, 2020 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.