Angular Material DatePicker: Date becomes one day before selected date
One thing we need to understand how Date work. let me go through some example that how we can create a date object.
new Date('2020-08-22') // 22 aug 2020(your expect result)
the output of the above date depended on your time zone when you pass date like that it considers as GMT.it add offset according to your time zone. let's say you are in +0500 than it will print
Sat Aug 22 2020 05:00:00 GMT+0500
it adds 5h to your date.
if you are in -0500 so it will
Fri Aug 21 2020 19:00:00 GMT-0500
if you want Date always give you the date that you pass without adding offset.
new Date(2020,07,22)
Sat Aug 22 2020 00:00:00 GMT+0500
It not add an hour(offset) to a date object.
I just resolve the issue by the second approach and it's working for me.
When we choose a date in the date picker, the selection is stored and manipulated in GMT (according to Greenwich timezone) time, but displayed back to the user in the formatted representation, taking into account user's current timezone. So stored and displayed dates are different (except of the users within timezone +0, like Greenwich).
When stringifying JS Date object, we get clear Greenwich timezone time, we can see it at https://time.is/GMT. What you probably expect to see is time representation formatted with your current timezone. See difference in my example.
// get current time
let date = new Date();
console.log('NATIVE JS DATE TIME', date.toString());
console.log('STRINGIFIED TIME', JSON.stringify(date));
console.log('FORMATTED TIME', `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
you can use very convenient moment's format()
function for displaying date.
I solved it by creating a custom date adapter (which inherits the native date adapter) and overriding create-date method to remove timezone offset
@Injectable({ providedIn: 'root' })
export class CustomDateAdapterService extends NativeDateAdapter {
public createDate(year: number, month: number, date: number): Date {
const localDate = super.createDate(year, month, date);
const offset = localDate.getTimezoneOffset() * 60000;
return new Date(localDate.getTime() - offset); // utcDate
}
}
you can have a look at complete gist here