Web Application Time Zone Issue
我们在中西部(东部标准时间)启动并运行服务器的ASP.Net 2.0 Web应用程序。此时,我们所有的客户都与服务器位于同一时区。我们将在亚利桑那州(Mountain Standard Time)在线提供另一台服务器。
我们通过C#codebehind DateTime.UtcNow将所有时间存储在SQL 2005数据库中。
在测试期间,我们遇到了一些时区转换问题。
我们的问题是,在网络浏览器中,我们的时间显示的是山地标准时间而不是我们正在测试的时区,即东部标准时间。
当我们输入新信息时,它会以UTC的形式存储在数据库中,但是当我们在浏览器中查看该信息时,它会显示Mountain Standard Time。
下面是从数据库中获取UTC值并在浏览器中显示的代码。
1 | lblUpdatedDate.Text = Convert.ToDateTime(dr["UpdatedDate"]).ToLocalTime().ToString(); |
上面的代码返回服务器所在的Mountain Standard Time,而不是运行浏览器的Eastern Standard Time。我们如何有时间显示用户所在的位置?
我遇到过同样的问题。我们将应用程序出售给与Web服务器位于不同时区的用户。我们没有以UTC格式存储任何时间信息,但实际上它正常工作。服务器时区中显示的时间正好落后3小时。我们所要做的只是添加一个时区下拉,以便他们可以为整个站点选择他们的时区(因为应用程序的唯一用户将在他们的时区)。我们保存了此设置,然后插入了一个函数来进行所有日期时间显示,并使用TimeZoneInfo命名空间从一个时区转换到另一个时区。它完美地运作。
到本地时间将始终在服务器端转换为物理位置。你有几个选择。
在使用ASP.NET之前我遇到过类似的事情。这是我的一般方法。
我发送JavaScript来做一个document.write。 JavaScript确定客户端与GMT的偏差。因此,您可以发送特定时间,然后让JavaScript对其执行加/减。
如果您使用的是.NET 3.5并且您知道用户所在的时区,则TimeZoneInfo就是您的朋友。如果您没有使用.NET 3.5,那么可以使用一些P / Invoke示例来获取TimeZone的实例,但如果您有权访问3.5,则值得避免。 (TimeZoneInfo有历史数据等,通常是首选方式。)
现在确定用户所在的时区是一个不同的问题 - 避免混淆的最简单方法是给他们选择。 (获取"现在"的偏移量仅为您提供有限的信息。)
只需将datetime存储为GMT格式。
有两个步骤:
使用Javascript在客户端检测不同的时区:
1 2 |
然后在服务器端,C#代码根据上面检测到的时区偏移将服务器时间转换为客户端时间:
1 2 3 4 5 6 | string queryStr = Request.QueryString["diffInMinutes"]; int diffInMinutes = 0; if (Int32.TryParse(queryStr, out diffInMinutes)) { clientTime = serverTime.ToUniversalTime().AddMinutes(diffInMinutes); } |
我认为一般的想法是不要将日期和时间本地化。直到你把它呈现给用户的时间。因此,除非人类要阅读它,否则它将保持UTC,GMT,CUT。另外一个注释使用日期/时间库,因此您不必太担心夏令时变化问题。
我们遇到了相同或类似的问题,远程客户端通过webservices调用我们的数据库,其中数据库和客户端位于不同的时区。
我们发现最简单的方法是指示数据集不关心时区,因此不会跨时区边界更改时间...
我们构建了一个实用程序方法(SetAllDateModes),它按表转换数据集中的所有日期时间字段 - 这是业务端(Foreach)和设置dateMode的调用:
1 2 3 4 5 6 7 8 | foreach (DataColumn dc in dt.Columns) { if (dc.DataType == typeof(DateTime)) { dc.DateTimeMode = dateMode; } } SetAllDateModes(dt, DataSetDateTime.Unspecified); |
DateSetDateTime.Unspecified不包含偏移量,因此没有转换。