我不知道如何更改 Material 2 Datepicker 的日期格式。我已经阅读了文档,但我不明白我实际需要做什么。Datepicker 默认提供的输出日期格式是: 6/9/2017
我想要的是将格式更改为像 9-Jun-2017
或其他任何格式。
文档https://material.angular.io/components/component/datepicker对我没有帮助。
我不知道如何更改 Material 2 Datepicker 的日期格式。我已经阅读了文档,但我不明白我实际需要做什么。Datepicker 默认提供的输出日期格式是: 6/9/2017
我想要的是将格式更改为像 9-Jun-2017
或其他任何格式。
文档https://material.angular.io/components/component/datepicker对我没有帮助。
这是我为此找到的唯一解决方案:
首先,创建常量:
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'},
}
};
然后您需要扩展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);
}
}
在格式函数中,您可以选择任何格式
最后一步是将其添加到模块提供程序中:
providers: [
{provide: DateAdapter, useClass: MyDateAdapter},
{provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS},
],
就这样了。我无法相信没有一种简单的方式可以通过@Input更改日期格式,但让我们希望它将在 material 2 的某个未来版本中实现(目前处于beta 6)。
import { DateAdapter, NativeDateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from "@angular/material/core";
- remborgconstructor() {super('en-US');}
添加到 MyDateAdapter
类中。 - crollywood伊戈尔的答案对我没有用,所以我直接在 Angular 2 Material 的 GitHub 上提问,有人给了我一个可行的答案:
首先编写您自己的适配器:
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();
}
}
创建你的日期格式:
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' },
}
};
将这两个提供给您的模块
providers: [
{
provide: DateAdapter, useClass: AppDateAdapter
},
{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}
]
更多信息在这里
编辑:对于那些输入手动时间格式被忽略的人,您可以按照以下方式覆盖NativeDateAdapter
的parse(value: any)
函数。
parse(value: any): Date | null {
const date = moment(value, 'DD/MM/YYYY');
return date.isValid() ? date.toDate() : null;
}
因此,自定义适配器的最终形式将如下所示。
import { NativeDateAdapter } from "@angular/material";
import * as moment from 'moment';
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();
}
parse(value: any): Date | null {
const date = moment(value, environment.APP_DATE_FORMAT);
return date.isValid() ? date.toDate() : null;
}
}
你只需要提供自定义的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'}
}
};
并将其添加到提供者列表中。
providers: [{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}]
工作中的 代码
对我有用的解决方法是:
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;
...
现在您可以选择最适合您的格式(例如 'd-MMM-y')。
很有可能您已经使用过一个库,它可以为您提供在JavaScript中操作(解析、验证、显示等)日期和时间的方便方法。如果您还没有使用过,可以尝试其中一个,例如moment.js。
使用moment.js实现自定义适配器看起来像这样。
创建CustomDateAdapter.ts并像这样实现:
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);
}
}
在你的app.module.ts文件中:
import { DateAdapter } from '@angular/material';
providers: [
...
{
provide: DateAdapter, useClass: CustomDateAdapter
},
...
]
就是这样。简单易行,无需重新发明轮子。
创建一个日期格式的常量。
export const DateFormat = {
parse: {
dateInput: 'input',
},
display: {
dateInput: 'DD-MMM-YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'MM/DD/YYYY',
monthYearA11yLabel: 'MMMM YYYY',
}
};
在应用程序模块中使用以下代码
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: DateFormat }
]
为什么不要使用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() {}
}
Robouste工作得非常好!!
我制作了一个简单的(Angular 4 "@angular/material": "^2.0.0-beta.10"),首先创建了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 {
}
只需导入它(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 {}
根据Arthur z和Gil Epshtain的原始想法,我将moment
更改为date-fns
。在angular @angular/material": "^10.0.2
中进行了测试。
创建CustomDateAdapter.ts
并按照以下方式实现:
import { NativeDateAdapter } from "@angular/material/core";
import { format } from 'date-fns';
import { es } from 'date-fns/locale'
export class CustomDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
var formatString = (displayFormat === 'input')? 'DD.MM.YYYY' : 'dd-MM-yyyy';
return format(date, formatString, {locale: es});
}
}
import { DateAdapter } from '@angular/material';
providers: [
...
{
provide: DateAdapter, useClass: CustomDateAdapter
},
...
]
我使用了@igor-janković提供的解决方案,但出现了“错误:未捕获(在承诺中):TypeError:无法读取未定义的属性'dateInput'”的问题。我意识到这个问题是因为MY_DATE_FORMATS
需要像type MdDateFormats
一样声明:
export declare type MdDateFormats = {
parse: {
dateInput: any;
};
display: {
dateInput: any;
monthYearLabel: any;
dateA11yLabel: any;
monthYearA11yLabel: any;
};
};
MY_DATE_FORMATS
的方式是: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'},
}
};
通过以上修改,该解决方案对我有效。
祝好