Is there a way to define the timezone for an appli

2020-07-18 09:07发布

Is there a way to define the timezone for an application in ASP.NET such that all times read from/compared to current server time are implicitly converted, or do I need to put in conversion statements as each and every DateTime.Now call?

3条回答
2楼-- · 2020-07-18 09:38

I am not sure about the latest evolutions of ASP, but this article from 2006 provides an interesting answer:

The problem is that timezone information is not directly available through the web browser. You could use heuristics to determine the correct time zone or you will have to store the timezone settings for a user based on their selection.

What follows may not be need with .Net 3.5 and its TimeZoneInfo..ConvertTime method, but still, for completeness sake:

Once you have the timezone settings you now need to translate the times. You should always store your date/time values in the DB in UTC. This eliminates many conversion issues. If you store the information in UTC then you need only translate from UTC to the user's local timezone when you display the data to them and you need to convert from their time zone to UTC when you get date/time values from them.

What makes this more difficult is the fact that the TimeZone class is not all that useful. Fortunately in v2.0 DateTime was updated to support an indicator on whether the time is in UTC or not. You can convert a DateTime to UTC using the DateTime.ToUniversalTime method. Unfortunately however you can't convert it back.

The ToLocalTime method uses the local time zone which, when run on the server, uses the server's time zone which isn't what you wanted. Even worse however is that you can't simply create a TimeZone object and use it as that support doesn't exist.

Michael Brumm created a nice little class for being able to create and use time zones easily. I personally use a heavily modified version of that code in my own apps and it works nicely. Here are the steps to convert from a DB UTC value to the local user's time zone.

1) Get the stored timezone value for the user
2) Create a SimpleTimeZone class to wrap it (using some mapping scheme that maps a DB value to the underlying Windows registry version)
3) Use the SimpleTimeZone.ToLocalTime method to convert the DateTime value to the local time.

For performance reasons you should probably get and initialize the SimpleTimeZone instance and cache it in the Items property for the length of the request so you don't have to keep creating it.

For converting from the user's local timezone to UTC do the reverse:

1) Get the stored timezone value from the user
2) Create a SimpleTimeZone class to wrap it
3) Use SimpleTimeZone.ToUniversalTime method to convert the DateTime to UTC.

查看更多
家丑人穷心不美
3楼-- · 2020-07-18 09:54

Allow me to answer this question directly.

Is there a way to define the timezone for an application in ASP.NET such that all times read from/compared to current server time are implicitly converted ...

No, this is not possible. There is no mechanism in .NET to change the local time zone on a per-thread or per-application basis. It can only be changed system-wide by the time zone settings of the machine the code is running on. See this answer also.

... or do I need to put in conversion statements as each and every DateTime.Now call?

You should not be using DateTime.Now in a web application. Because the time zone setting of your server can easily be changed, you should design your application to ignore it. That means using DateTime.UtcNow when reading the current system time. Alternatively, you can use DateTimeOffset with its DateTimeOffset.Now or DateTimeOffset.UtcNow properties.

See also: The Case Against DateTime.Now

When you need to work with particular user's local time, then yes - you must put in conversions for each and every usage. You can use the TimeZoneInfo class to accomplish this.

You also might consider using Noda Time, which offers an implementation of the IANA time zone database, and is a much better API in general.

查看更多
虎瘦雄心在
4楼-- · 2020-07-18 10:04

Internally use DateTime.UtcNow. For .NET 3.5, check out TimeZoneInfo.ConvertTime.

查看更多
登录 后发表回答