Formato Angular 2 Material 2 formato de data do leitor de dados
documentação https://material.angular.io/components/component/datepicker não me ajuda nada. Obrigado antecipadamente.
15 answers
Primeiro, criar 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'},
}
};
Então tens que estender o Nomadapter Natived:
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);
}
}
Na função de formato, você pode escolher qualquer formato que você quiser
E o último passo, você tem que adicioná-lo aos fornecedores de módulos:
providers: [
{provide: DateAdapter, useClass: MyDateAdapter},
{provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS},
],
E é isso. Eu não posso acreditar que não há nenhuma maneira fácil de mudar o formato de data através do @ Input, mas vamos esperar que ele será implementado em alguma versão futura de material 2 (actualmente beta 6 ).
-
Primeiro escreva o seu adaptador:
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(); } }
-
Crie o seu formato de data:
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' }, } };
-
Forneça esses dois ao seu módulo
providers: [ { provide: DateAdapter, useClass: AppDateAdapter }, { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS } ]
Mais informações aqui
EDIT: para aqueles que estão tendo o problema da entrada manual está sendo não respeitado com o formato, você pode anular a função parse(value: any)
a partir de NativeDateAdapter
Como se segue.
parse(value: any): Date | null {
const date = moment(value, 'DD/MM/YYYY');
return date.isValid() ? date.toDate() : null;
}
Então, o adaptador personalizado tomará a forma final como se segue.
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;
}
}
Você só precisa fornecer um costume 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'}
}
};
E adiciona-o aos fornecedores.
providers: [{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}]
A funcionar código
O trabalho em torno do qual funciona para mim é:
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;
...
Então agora você pode ter o formato (ex. isso funciona melhor para ti.
Implementar o adaptador personalizado usando o momento.o js ficaria assim.
Criar Um Mapa Personalizado.TS e implementá-lo assim:
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);
}
}
No seu app.modulo.ts:
import { DateAdapter } from '@angular/material';
providers: [
...
{
provide: DateAdapter, useClass: CustomDateAdapter
},
...
]
É isso. Simples, fácil e sem necessidade de reinventar bicicletas.
Tornei fácil um (Angular 4 "@angular / material": "^2. 0. 0-beta.10") foi o primeiro a fazer um "datepicker".modulo.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 {
}
Basta importá-lo (app.modulo.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 {}
Porque não usar o tubo de dados Angular?
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() {}
}
Crie uma constante para o formato de data.
export const DateFormat = {
parse: {
dateInput: 'input',
},
display: {
dateInput: 'DD-MMM-YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'MM/DD/YYYY',
monthYearA11yLabel: 'MMMM YYYY',
}
};
E usar o código abaixo dentro do módulo app
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: DateFormat }
]
Eu usei a solução proposta por @igor-janković e tive o problema de "erro: Uncaught (na promessa): erro tipográfico: não é possível ler a propriedade 'dateInput' de indefinido". Eu percebi que este problema era porque MY_DATE_FORMATS
precisa ser declarado como type MdDateFormats
:
export declare type MdDateFormats = {
parse: {
dateInput: any;
};
display: {
dateInput: any;
monthYearLabel: any;
dateA11yLabel: any;
monthYearA11yLabel: any;
};
};
Então, a forma correcta de declarar 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'},
}
};
Com a modificação acima, a solução funciona para mim.
Relativamente a
A data Angular do material irá devolver o formato abaixo (apenas consola.log to see it)
Momento {_isamentobject: true, _i: {...}, _isUTC: false, _pf: { ... }, _locale: Locale,...} _d: Thu 28 2021 00: 00: 00 GMT+0800 (Hora Padrão de Singapura) {}
_i: {ano: 2021, mês: 0, Data: 28}
_estamomentobject: true........
Por isso, converto para uma data curta usando os literais de modelos
Data Limite = ${due_date._i.year}-${due_date._i.month + 1}-${due_date._i.date}
Vais ter o formato "AAAA-MM-DD"
Criar uma data de arquivo.adaptador.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.modulo.ts
providers: [
DatePipe,
{
provide: DateAdapter, useClass: AppDateAdapter
},
{
provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
}
]
App.componente.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.componente.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>
Ideia Original de Arthur z e Gil Epshtain, eu mudei moment
para date-fns
.
testada em angular @angular/material": "^10.0.2
.
Criar CustomDateAdapter.ts
e implementá-lo assim:
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});
}
}
Na tua aplicação .modulo.ts:
import { DateAdapter } from '@angular/material';
providers: [
...
{
provide: DateAdapter, useClass: CustomDateAdapter
},
...
]
import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
// Depending on whether rollup is used, moment needs to be imported differently.
// Since Moment.js doesn't have a default export, we normally need to import using the `* as`
// syntax. However, rollup creates a synthetic default module and we thus need to import it using
// the `default as` syntax.
import * as _moment from 'moment';
// tslint:disable-next-line:no-duplicate-imports
import {default as _rollupMoment} from 'moment';
const moment = _rollupMoment || _moment;
// See the Moment.js docs for the meaning of these formats:
// https://momentjs.com/docs/#/displaying/format/
export const MY_FORMATS = {
parse: {
dateInput: 'LL',
},
display: {
dateInput: 'LL',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
/** @title Datepicker with custom formats */
@Component({
selector: 'datepicker-formats-example',
templateUrl: 'datepicker-formats-example.html',
providers: [
// `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
// application's root module. We provide it at the component level here, due to limitations of
// our example generation script.
{
provide: DateAdapter,
useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
},
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
],
})
export class YourDatepickerUsedComponent {
date = new FormControl(moment());
}
Ligação: https://material.angular.io/components/datepicker/examples e procurar "Datepicker com formatos personalizados"
Da documentação:
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 {}
- Adicione o necessário ao NgModule.
- Crie o seu próprio formato-MY_NATIVE_ DATE_ formats
Aqui está a minha solução com a menor quantidade de código e usando o MAT_NATIVE_DATE_FORMATS
.
- Declare os seus próprios formatos de data
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,
}
};
- usa-os
@Component({
selector: 'app-vacation-wizard',
templateUrl: './vacation-wizard.component.html',
styleUrls: ['./vacation-wizard.component.scss'],
providers: [
{ provide: MAT_DATE_FORMATS, useValue: GRI_DATE_FORMATS },
]
})
Não se esqueça de definir a linguagem apropriada!
this.adapter.setLocale(this.translate.currentLang);
É tudo!