I am using angular material 2 Date-Picker component
The only string input it understands is in ISO date format
Ex. \"2017-11-13T10:39:28.300Z\"
But i
I have a very easy solution.
// create date.helpers.ts
import { formatDate } from '@angular/common';
import { Injectable } from '@angular/core';
import { NativeDateAdapter } from '@angular/material/core';
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' }
}
};
@Injectable({
providedIn: 'root'
})
export class PickDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
return formatDate(date, 'dd/MM/yyyy', this.locale);;
} else {
return date.toDateString();
}
}
}
add this to
// your.module.ts
providers: [
NomineeService,
{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'legacy' } },
{ provide: DateAdapter, useClass: PickDateAdapter },
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
]
//shared.service.ts
formatDate(date): string {
const _date = new Date(date);
const day = _date.getDate();
const month = _date.getMonth() + 1;
const year = _date.getFullYear();
return `${year}-${month}-${day}`;
}
formatTime(date: Date): string {
const _date = new Date(date);
const hours = _date.getHours()
const minutes = _date.getMinutes();
const seconds = _date.getSeconds();
return `${hours}:${minutes}:${seconds}`;
}
toDateTimestamp(date: Date): string {
const dateStamp = this.formatDate(date);
const timeStamp = this.formatTime(date);
return `${dateStamp} ${timeStamp}`
}
calculateDays(fromDate, toDate): number {
const FromDate = new Date(fromDate);
const ToDate = new Date(toDate);
const difference = ToDate.getTime() - FromDate.getTime();
const days = Math.round((difference / (1000 * 60 * 60 * 24)));
return days;
}
The best solution would be to use ControlValueAccessor and make a custom input component, this will have you in control of input and output of the component.
update:
Here is the reference implementation using this approach reproduced by Moutaz-homsi
https://stackblitz.com/edit/angular-dlxnmx?file=app%2Fcva-date.component.ts
Not sure, if you are already doing this but I found some information that might give you some idea on your implementation.
As of today the Angular Material Date Module
supports two ways of providing a date value MatNativeDateModule
and MatMomentDateModule
. The MatNativeDateModule
accepts ISO 8601
format by default. But since you don't want to use ISO
format, I would suggest using MatMomentDateModule
(Moment.js implementation).
When we use the MatMomentDateModule
the date object is not anymore a JavaScript Date
object but instead is a Moment.js instance
(take advantage of methods available to a Moment js instance like format()
). There are basic to intermediate examples available on Material Date Picker docs page using the Moment.js. Also, once your date is a Moment.js instance, you could overwrite the methods(format, parse.) from MomentDateAdapter instead of native date adapter.
you can change it's format like this:
const Date = Date.replace(/-/g, '/')
First import moment and set format . https://momentjs.com/
import * as moment from 'moment';
setDateFormat(date) {
this.myDate = moment(date).format('YYYY/MM/DD HH:mm:ss');
}
You probably need to write a completely new adapter or use the moment adapter. @angular/material-moment-adapter:5.0.0-rc0
. The moment adapter uses momentjs and allows you much more control on the output format.
Moment is also able to parse different input formats.
The NativeDateAdapter
uses the Intl API to format the output date. You can try to provide a custom MAT_NATIVE_DATE_FORMATS instance but I am not sure how far this gets you.
EDIT
You are currently using 2.0.0-beta12 of angular/material, that doesn't fit with your code based on 5.0.0-rc0/master. There are changes in the codebase, especially the deserialize function which is not present in 2.0.0-beta12, that's why it is not being called. If you can't update to angular 5 then look at MatDatepickerInput.setValue/coerceDateProperty
which sets the date into your FormControl
.