Angular DatePicker stuff: date becomes one day before selected date

I am using the latest Angular 4 and Angular-Material2-2.0.0-beta7. This is my template using MdDatePicker

:

<md-input-container fxFlex="33" class="birthday-container">
    <input mdInput name="birthday" placeholder="Birthday" required [(ngModel)]="member.birthday" [mdDatepicker]="birthdayPicker">
    <button mdSuffix [mdDatepickerToggle]="birthdayPicker"></button>
</md-input-container>
<md-datepicker #birthdayPicker></md-datepicker>

      

In app.module, here is the provider:

{provide: DateAdapter, useClass: NativeDateAdapter}

      

And member.birthday

there is Date

. But when JSON.stringify(member.birthday)

, it becomes one day before the selected date. For example:

Select the 2017-4-1

date in the picker and the string result is 2017-03-31T13:00:00.000Z

.

This post raised the same question, but I'm not sure how to apply moment.js

to code.

+6


source to share


2 answers


When we select a date in the date picker, the selection is saved and processed in GMT (Greenwich timezone), but displayed back to the user in a formatted view based on the user's current time zone. Therefore, the stored and displayed dates are different (except for users in the +0 time zone, such as Greenwich).

When formatting a JS Date object, we get a clear Greenwich Mean Time, we can see it at https://time.is/GMT . What you probably expect to see is a time representation formatted with your current time zone. See the 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()}`);
      

Run codeHide result


you can use a very convenient moment format()

to display the date.

+2


source


I solved this problem by creating a custom date adapter (which inherits its own date adapter) and overriding the create-date method to remove the 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 take a look at the full gist here

0


source







All Articles