dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.21k stars 9.95k forks source link

discussion of TimeZone handing in asp.net core‘s Server side rendered content #33510

Open John0King opened 3 years ago

John0King commented 3 years ago

question:

  1. how do we handle different timezone on the server (mvc/razor pages) and for multiple region site ?
  2. how time be edit/update in en-us region ? (I'm in China, and only have 1 time, BeiJing Time +8)

background

today, when we using Angular/React/Vue to build a system, we can take advantage of the browser and client computer's timezone. and Date is always local to us, so there are no problem for us to edit and read the time.

but what about a MVC site ? now MVC bind time default to UTC time (that make sqlserver store +0 time), and Mysql will store UTC time any way , and we do not know the client's timezone on the server, so how we render the DateTimeOffset and DateTime ?

My opinion

  1. we should have RequestTimezone concept, and a middleware to set and get, and InputTaghelper should use that.
  2. A timezone map of country, there are only a few country have multiple timezone, (US , Russian,Canada, Australia )

explain 1 : we can use a small javascript to detect the timezone of browser and set a cookie , and RequestTimeZoneMiddleware read this cookie and set IRequestTimeZone.Current explain 2: direct get a timezone from culture and set it to IRequestTimeZone.Current only if the Current is null.

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

mkArtakMSFT commented 3 years ago

Thanks for contacting us. This is indeed a gap in the framework and we'll consider addressing it in the future.

John0King commented 3 years ago

@mkArtakMSFT May I ask how time(input) be edit/update in en-us region?

John0King commented 3 years ago

I think , the best option for is is TimeZoneInfo.Current as using a AsyncLocal<T> as a backend field, because put IRequestTimeZone.Current in request pipeline have a cost for every request (especially when a app do not need timezone detect , for example , a single region website).

but the problem is TimeZoneInfo.Current must add in Runtime Repo,
once it add to TimeZoneInfo, the RequestTimeZone middleware will be optional,
that means that you can use that middleware to set the current timezone , and it will be default to Local timezone when you not use RequestTimeZone middleware. and appliation can safely use the TimeZoneInfo.Current everywhere just like CultureInfo.Current .

I will post a issue in dotnet/runtime later.

Clockwork-Muse commented 3 years ago

A timezone map of country, there are only a few country have multiple timezone, (US , Russian,Canada, Australia )

This is trickier than you think, because timezones are political. For instance, there's (or were) apparently multiple timezones for Israel, because Israelis and Palestinians had different timezone wishes. This is assuming that IP detection works correctly in the first place, which is not a given.

explain 1 : we can use a small javascript to detect the timezone of browser and set a cookie , and RequestTimeZoneMiddleware read this cookie and set IRequestTimeZone.Current

In any website with a user profile, timezone should be a (user modifiable) property on the user profile. Although you can set/read a cookie for this, it may be more beneficial to plumb a session profile throughout, for anonymous/unregistered users.

I think , the best option for is is TimeZoneInfo.Current as using a AsyncLocal<T> as a backend field, because put IRequestTimeZone.Current in request pipeline have a cost for every request (especially when a app do not need timezone detect , for example , a single region website).

As a safety measure, akin to wearing a seat belt in a car, servers should still always be set to UTC. This ask also ignores the fact that you may need to work with multiple timezones (or even cultures) in a given request (some calendaring applications). Timezones should instead be loaded from user or entity profiles, even for supposed "single region" websites (although I think the change unlikely, China could mandate tomorrow that they would switch to multiple timezones).

John0King commented 3 years ago

timezone map of country is just one of the timezone detect method(same as js+cookies), because not every website has "User" , for example Doc site, Survey site. and "timezone map of country" means "timezone map of cultures" not IP detection (and of cause IP detection can be a timezone detect method too )

akin to wearing a seat belt in a car, servers should still always be set to UTC.

use UTC also have problem, explain: I live in Chine (+8:00), and people edit Time using "2021-6-30 08:00" instead of 2021-6-30T00:00Z , people are using local time format, and this time handled by modelbinding and InputTagHelper have serious problem: database value: 2021-6-30 08:00 +08:00 show in input taghelper : 2021-6-30 08:00 model binder to UTC : 2021-6-30 08:00 +00:00 save in mySql database : 2021-6-30 08:00 +00:00 (only support utc time , no offset)

and this have no problem for Vue/Angular/React, because the those input component will give you a Date value and post using Json iso time format

Clockwork-Muse commented 3 years ago

timezone map of country is just one of the timezone detect method(same as js+cookies), because not every website has "User" , for example Doc site, Survey site.

What I was getting at was you'd create an "anonymous" (not logged in) user profile that gets plumbed through, as if they were a normal user.

and "timezone map of country" means "timezone map of cultures" not IP detection (and of cause IP detection can be a timezone detect method too )

... this runs into the exact same problem.

use UTC also have problem, explain: I live in Chine (+8:00), and people edit Time using "2021-6-30 08:00" instead of 2021-6-30T00:00Z , people are using local time format, and this time handled by modelbinding and InputTagHelper have serious problem: database value: 2021-6-30 08:00 +08:00 show in input taghelper : 2021-6-30 08:00 model binder to UTC : 2021-6-30 08:00 +00:00 save in mySql database : 2021-6-30 08:00 +00:00 (only support utc time , no offset)

Sure, but this isn't an issue with server config. It's an issue with your application not being written to handle timezone passing, or timezone changes, and includes the use of the proper types in mysql.

You should always be explicit about which timezone (and offset) you're dealing with at any particular point in your application, and may include requiring specific input fields for it.

mysql itself has two main date/time types, DATETIME (which is zone ignorant, and you'd need to explicitly store offset and timezone id), and TIMESTAMP (which is zone agnostic - it doesn't really store it in UTC per se). Which one of those two you want depend on what type of information you're storing - if it's any type of "future" information you absolutely must use DATETIME+zone id+offset (and possibly a derived TIMESTAMP field for speeding up some queries, but the source of truth would be the other fields). If it's "logged" or reporting information you often want TIMEZONE (but not always - sometimes you need to do the same work as for "future" information).

John0King commented 2 years ago

@mkArtakMSFT any progresson this? and how you resolve the "date picker" and input-taghelper + "model binding" issue?

icnocop commented 2 years ago

For reference: https://github.com/vivet/Vivet.AspNetCore/tree/master/Vivet.AspNetCore.RequestTimeZone

RacerDelux commented 10 months ago

I wonder if this is a dotnet issue or a http issue.

Really web requests should just have a timezone header that your ISP could populate. That gives no more information that is already obtainable by an IP and would significantly improve handling timezones on a server.

This would also get past many of the issues above where timezones could be political. Let the ISPs hash that out. (IE, when you sign up for internet, if there are indeed multiple timezones, you can let your ISP know which one you want to be attributed to your account).

Clockwork-Muse commented 10 months ago

Really web requests should just have a timezone header that your ISP could populate.

This would require that your ISP perform SSL interception, or that you pass the request unencrypted. I like my security more than I trust my ISP.

This would also get past many of the issues above where timezones could be political. Let the ISPs hash that out. (IE, when you sign up for internet, if there are indeed multiple timezones, you can let your ISP know which one you want to be attributed to your account).

That assumes that your ISP isn't also "political". In the Israel example I cited earlier, I can guarantee you they're only going to supply the Israel timezone.

A much better way to handle this type of behavior is if browsers could populate a well-known header with the value themselves, since presumably you've set your computer to the timezone you want.

RacerDelux commented 9 months ago

A much better way to handle this type of behavior is if browsers could populate a well-known header with the value themselves, since presumably you've set your computer to the timezone you want.

Sure, I like that. It should just pass your UTC offset. But what are the odds of browsers actually supporting this... Or... what is keeping it from being implemented.

Clockwork-Muse commented 9 months ago

It should just pass your UTC offset.

More important is the zone, because that will communicate things like DST and historical rules. Offet is insufficient/probably unnecessary.

Or... what is keeping it from being implemented.

You'd need to get an RFC to propose such a header, although browsers regularly add their own non-standard headers with extra features. Note that this assumes that you actually fully render the page on the server, including offset calculations and formatting. Whether or not this is realistic depends on a variety of factors, most often depending on what the data field represents.