I need help. I don\'t know how to change the date format of the material 2 datepicker. I\'ve read documentation but I don\'t understand what I actually need to do. Output da
From documentation:
Customizing the parse and display formats
The MD_DATE_FORMATS object is just a collection of formats that the datepicker uses when parsing and displaying dates. These formats are passed through to the DateAdapter so you will want to make sure that the format objects you're using are compatible with the DateAdapter used in your app. This example shows how to use the native Date implementation from material, but with custom formats.
@NgModule({
imports: [MdDatepickerModule],
providers: [
{provide: DateAdapter, useClass: NativeDateAdapter},
{provide: MD_DATE_FORMATS, useValue: MY_NATIVE_DATE_FORMATS},
],
})
export class MyApp {}
Create a constant for date format.
export const DateFormat = {
parse: {
dateInput: 'input',
},
display: {
dateInput: 'DD-MMM-YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'MM/DD/YYYY',
monthYearA11yLabel: 'MMMM YYYY',
}
};
And Use the below code inside app module
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: DateFormat }
]
create a file date.adapter.ts
import { NativeDateAdapter, DateAdapter, MAT_DATE_FORMATS, MatDateFormats } from "@angular/material";
export class AppDateAdapter 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: string): string {
if (displayFormat == "input") {
let day = date.getDate();
let month = date.getMonth() + 1;
let year = date.getFullYear();
return year + '-' + this._to2digit(month) + '-' + this._to2digit(day) ;
} else if (displayFormat == "inputMonth") {
let month = date.getMonth() + 1;
let year = date.getFullYear();
return year + '-' + this._to2digit(month);
} else {
return date.toDateString();
}
}
private _to2digit(n: number) {
return ('00' + n).slice(-2);
}
}
export const APP_DATE_FORMATS =
{
parse: {
dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
},
display: {
dateInput: 'input',
monthYearLabel: 'inputMonth',
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'},
}
}
app.module.ts
providers: [
DatePipe,
{
provide: DateAdapter, useClass: AppDateAdapter
},
{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}
]
app.component.ts
import { FormControl } from '@angular/forms';
import { DatePipe } from '@angular/common';
@Component({
selector: 'datepicker-overview-example',
templateUrl: 'datepicker-overview-example.html',
styleUrls: ['datepicker-overview-example.css'],
providers: [
DatePipe,
{
provide: DateAdapter, useClass: AppDateAdapter
},
{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}
]
})
export class DatepickerOverviewExample {
day = new Date();
public date;
constructor(private datePipe: DatePipe){
console.log("anh "," " +datePipe.transform(this.day.setDate(this.day.getDate()+7)));
this.date = new FormControl(this.datePipe.transform(this.day.setDate(this.day.getDate()+7)));
console.log("anht",' ' +new Date());
}
}
app.component.html
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date" [formControl]="date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
I used the solution propose by @igor-janković and had the problem of "Error: Uncaught (in promise): TypeError: Cannot read property 'dateInput' of undefined". I realized that this problem was because MY_DATE_FORMATS
need to be declare like type MdDateFormats
:
export declare type MdDateFormats = {
parse: {
dateInput: any;
};
display: {
dateInput: any;
monthYearLabel: any;
dateA11yLabel: any;
monthYearA11yLabel: any;
};
};
So, the correct way of declare MY_DATE_FORMATS
is:
const MY_DATE_FORMATS:MdDateFormats = {
parse: {
dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
},
display: {
dateInput: 'input',
monthYearLabel: {year: 'numeric', month: 'short'},
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'},
}
};
With the above modification the solution work for me.
Regards
The work around that works for me is:
my.component.html:
<md-input-container>
<input mdInput disabled [ngModel]="someDate | date:'d-MMM-y'" >
<input mdInput [hidden]='true' [(ngModel)]="someDate"
[mdDatepicker]="picker">
<button mdSuffix [mdDatepickerToggle]="picker"></button>
</md-input-container>
<md-datepicker #picker></md-datepicker>
my.component.ts :
@Component({...
})
export class MyComponent implements OnInit {
....
public someDate: Date;
...
So now you can have the format (Ex. 'd-MMM-y') that works best for you.
Here's my solution with the least amount of code and using the MAT_NATIVE_DATE_FORMATS
.
import { MatDateFormats, MAT_NATIVE_DATE_FORMATS } from '@angular/material';
export const GRI_DATE_FORMATS: MatDateFormats = {
...MAT_NATIVE_DATE_FORMATS,
display: {
...MAT_NATIVE_DATE_FORMATS.display,
dateInput: {
year: 'numeric',
month: 'short',
day: 'numeric',
} as Intl.DateTimeFormatOptions,
}
};
@Component({
selector: 'app-vacation-wizard',
templateUrl: './vacation-wizard.component.html',
styleUrls: ['./vacation-wizard.component.scss'],
providers: [
{ provide: MAT_DATE_FORMATS, useValue: GRI_DATE_FORMATS },
]
})
Don't forget to set the appropriate language!
this.adapter.setLocale(this.translate.currentLang);
That's all!