问题
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 date format which datepicker provides by default is f.e.: 6/9/2017
What I'm trying to achieve is to change format to the 9-Jun-2017 or any other.
Documentation https://material.angular.io/components/component/datepicker doesn't help me at all. Thanks in advance
回答1:
Here is the only solution I found for this one:
First, create const:
const MY_DATE_FORMATS = {
parse: {
dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
},
display: {
// dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
dateInput: 'input',
monthYearLabel: {year: 'numeric', month: 'short'},
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'},
}
};
Then you have to extend NativeDateADapter:
export class MyDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat == "input") {
let day = date.getDate();
let month = date.getMonth() + 1;
let year = date.getFullYear();
return this._to2digit(day) + '/' + this._to2digit(month) + '/' + year;
} else {
return date.toDateString();
}
}
private _to2digit(n: number) {
return ('00' + n).slice(-2);
}
}
In format function, you can choose whatever format you want
And the last step, you have to add it into module providers:
providers: [
{provide: DateAdapter, useClass: MyDateAdapter},
{provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS},
],
And that's it. I can not believe that there is no some easy way to change date format through the @Input but let's hope it will be implemented in some future version of material 2 (currently beta 6).
回答2:
Igor's answer didn't work for me so I asked directly on Angular 2 Material's github and someone gave me that answer which worked for me :
First write your own adapter :
import { NativeDateAdapter } from "@angular/material"; export class AppDateAdapter extends NativeDateAdapter { format(date: Date, displayFormat: Object): string { if (displayFormat === 'input') { const day = date.getDate(); const month = date.getMonth() + 1; const year = date.getFullYear(); return `${day}-${month}-${year}`; } return date.toDateString(); } }
Create your date format :
export const APP_DATE_FORMATS = { 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' }, } };
Provide those two to your module
providers: [ { provide: DateAdapter, useClass: AppDateAdapter }, { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS } ]
More infos here
回答3:
You just need to provide a custom MAT_DATE_FORMATS
export const APP_DATE_FORMATS = {
parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
display: {
dateInput: {month: 'short', year: 'numeric', day: 'numeric'},
monthYearLabel: {year: 'numeric'}
}
};
and add it to providers.
providers: [{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}]
Working code
回答4:
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.
回答5:
There's a high chance that you already use a library that provides you with an convinient way of manipulating (parsing, validating, displaying, etc.) dates and times in JavaScript. If you dont, take a look at one of them, for example moment.js.
Implementing your custom adapter using moment.js would look like this.
Create CustomDateAdapter.ts and implement it like this:
import { NativeDateAdapter } from "@angular/material";
import * as moment from 'moment';
export class CustomDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
moment.locale('ru-RU'); // Choose the locale
var formatString = (displayFormat === 'input')? 'DD.MM.YYYY' : 'LLL';
return moment(date).format(formatString);
}
}
In your app.module.ts:
import { DateAdapter } from '@angular/material';
providers: [
...
{
provide: DateAdapter, useClass: CustomDateAdapter
},
...
]
That's it. Simple, easy and no need of reinventing bicycles.
回答6:
Robouste worked perfect!!
I made easy one (Angular 4 "@angular/material": "^2.0.0-beta.10") first made datepicker.module.ts
import { NgModule } from '@angular/core';
import { MdDatepickerModule, MdNativeDateModule, NativeDateAdapter, DateAdapter, MD_DATE_FORMATS } from '@angular/material';
class AppDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
return `${year}-${month}-${day}`;
} else {
return date.toDateString();
}
}
}
const APP_DATE_FORMATS = {
parse: {
dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
},
display: {
// dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
dateInput: 'input',
monthYearLabel: {year: 'numeric', month: 'short'},
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'},
}
};
@NgModule({
declarations: [ ],
imports: [ ],
exports: [ MdDatepickerModule, MdNativeDateModule ],
providers: [
{
provide: DateAdapter, useClass: AppDateAdapter
},
{
provide: MD_DATE_FORMATS, useValue: APP_DATE_FORMATS
}
]
})
export class DatePickerModule {
}
just import it (app.module.ts)
import {Component, NgModule, VERSION, ReflectiveInjector} from '@angular/core'//NgZone,
import { CommonModule } from '@angular/common';
import {BrowserModule} from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import { DatePickerModule } from './modules/date.picker/datepicker.module';
@Component({
selector: 'app-root',
template: `
<input (click)="picker.open()" [mdDatepicker]="picker" placeholder="Choose a date" [(ngModel)]="datepicker.SearchDate" >
<md-datepicker-toggle mdSuffix [for]="picker"></md-datepicker-toggle>
<md-datepicker #picker touchUi="true" ></md-datepicker>
`,
})
export class App{
datepicker = {SearchDate:new Date()}
constructor( ) {}
}
@NgModule({
declarations: [ App ],
imports: [ CommonModule, BrowserModule, BrowserAnimationsModule, FormsModule, DatePickerModule],
bootstrap: [ App ],
providers: [ ]//NgZone
})
export class AppModule {}
回答7:
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 }
]
回答8:
Why to not use Angular DatePipe?
import {Component} from '@angular/core';
import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material';
import {FormControl} from '@angular/forms';
import {DatePipe} from '@angular/common';
export const PICK_FORMATS = {
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'}
}
};
class PickDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
return new DatePipe('en-US').transform(date, 'EEE, MMM dd, yyyy');
} else {
return date.toDateString();
}
}
}
@Component({
selector: 'custom-date',
template: `<mat-form-field>
<input matInput [formControl]="date" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>`,
providers: [
{provide: DateAdapter, useClass: PickDateAdapter},
{provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
]
})
export class DateComponent {
date = new FormControl(new Date());
constructor() {}
}
回答9:
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
回答10:
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>
回答11:
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 {}
- Add required to NgModule.
- Create your own format - MY_NATIVE_DATE_FORMATS
来源:https://stackoverflow.com/questions/44452966/angular-2-material-2-datepicker-date-format