Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

day incorrect in angular material datepicker

When I select a date I see the correct date in the field but, when I save, the datepicker send the day before the date I have selected ( 3 hours offset ) i am using angular reactive form and MatMomentDateModule for date picker .

the problem is related to timezones but i just want to save the same date that the user enter to database .

Code repreduced here : https://stackblitz.com/edit/angular-material-moment-adapter-example-kdk9nk?file=app%2Fapp.module.ts

issue on stackblitz

issue related to this on githup :

https://github.com/angular/material2/issues/7167

Any help is appreciated , and i think a lot of developers need a solution for this .

like image 482
Motaz Homsi Avatar asked Feb 09 '18 16:02

Motaz Homsi


2 Answers

Two days ago, at https://github.com/angular/material2/issues/7167, Silthus posted his workaround that overrides the MomentJsDataAdapter. I tried it and it worked as a charm from anywhere in the globe.

First he added a MomentUtcDateAdapter that extends MomentDateAdapter

import { Inject, Injectable, Optional } from '@angular/core'; import { MAT_DATE_LOCALE } from '@angular/material';    import { MomentDateAdapter } from '@angular/material-moment-adapter'; import { Moment } from 'moment'; import * as moment from 'moment';  @Injectable() export class MomentUtcDateAdapter extends MomentDateAdapter {    constructor(@Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string) {     super(dateLocale);   }    createDate(year: number, month: number, date: number): Moment {     // Moment.js will create an invalid date if any of the components are out of bounds, but we     // explicitly check each case so we can throw more descriptive errors.     if (month < 0 || month > 11) {       throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);     }      if (date < 1) {       throw Error(`Invalid date "${date}". Date has to be greater than 0.`);     }      let result = moment.utc({ year, month, date }).locale(this.locale);      // If the result isn't valid, the date must have been out of bounds for this month.     if (!result.isValid()) {       throw Error(`Invalid date "${date}" for month with index "${month}".`);     }      return result;   } } 

And then in the AppModule component, you have to do this:

providers: [     ...     { provide: MAT_DATE_LOCALE, useValue: 'en-GB' },     { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },     { provide: DateAdapter, useClass: MomentUtcDateAdapter },     ... ], 
like image 158
Bruno Cerecetto Avatar answered Sep 21 '22 22:09

Bruno Cerecetto


Just use option useUtc: true for MatMomentDateAdapter:

import { MatMomentDateModule, MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';  @NgModule({   exports: [     MatMomentDateModule,     // ...   ],   providers: [     { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }   ], }) export class CustomModule { } 
like image 24
Interloper Avatar answered Sep 25 '22 22:09

Interloper