angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.31k stars 6.72k forks source link

bug(material/datepicker): Re-evaluate how the MatDatepicker handles timezones #11027

Open Maximaximum opened 6 years ago

Maximaximum commented 6 years ago

Bug, feature request, or proposal:

Documentation request

What is the expected behavior?

The moment object returned by selecting a date with Datepicker should have no timezone information (or UTC)

What is the current behavior?

Currently the moment object looks like this: Wed Apr 18 2018 00:00:00 GMT+0300 (The user is located in GMT+3, so his timezone is used)

What is the use-case or motivation for changing an existing behavior?

I wonder how to make my matDatepicker return UTC dates so that they are independent of the timezone the user is currently in. I've found lots of issues regarding this (https://github.com/angular/material2/issues/7167), but no clear and simple explanation on how to easily achieve that.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 5.2.0, Angular Material 6.0.0-beta.4, Typescript 2.5.3, ANY browser (not just IE!)

Is there anything else we should know?

I'm importing MatMomentDateModule, so all the dates in the app are momentjs dates.

Silthus commented 6 years ago

Take a look at the custom date adapter here: https://github.com/angular/material2/issues/7167#issuecomment-385627217

Maximaximum commented 6 years ago

@Silthus I think that such an example should be included into the documentation itself, because using UTC would be a very popular scenario.

anschm commented 3 years ago

The NativeDateAdapter does not support UTC if you pick a date. Thats because of the following function doesn't use setUTCFullYear and setUTCHours to set this parameters.

/* Creates a date but allows the month and date to overflow. / private _createDateWithOverflow(year: number, month: number, date: number) { // Passing the year to the constructor causes year numbers <100 to be converted to 19xx. // To work around this we use setFullYear and setHours instead. const d = new Date(); d.setFullYear(year, month, date); d.setHours(0, 0, 0, 0); return d; }

I think setUTCHours and setUTCFullYear should be used at this function. The MatMomentDataAdapter can be configured to use UTC. This works fine, but there are lots of DateValidators which can not be used with MomentJs. So in my opinion its absolut necessary to fix the NativeDataAdapter to use UTC.

ZbigniewRA commented 3 years ago

This is actually a fundamental bug in DatePicker. Bug #7167 was closed without really understanding what the issue is.

The issue is that a date picker must always operate on dates without a timezone. Local-to-utc or utc-to-local conversions (of which there are many in the code) make no sense for a DatePicker, because it doesn't represent a point in time, but rather a range. And therefore all conversions (that all assume one arbitrary point in that range) will provide inconsistent behaviour depending on the locale. Using locale here doesn't fix the inconsistency, but introduces it!

Example:

So in order to know which date user have chosen we need both date from the date picker AND his locale. The timepoint value we got is meaningless in itself. Storing it in a database for example is always a bug.

The correct behaviour would be as follows:

If you, dear reader, still have doubts about it please do the following experiment:

ZbigniewRA commented 3 years ago

Please change the docs label to bug.