关于c#:Web应用程序时区问题

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命名空间从一个时区转换到另一个时区。它完美地运作。


到本地时间将始终在服务器端转换为物理位置。你有几个选择。

  • 将UTC的偏移值存储到用户,保留UTC时间
  • 通过JS做转换客户端(不优雅,也不合适,在我看来)
  • 查看一些MSDN建议和Timezone名称空间

  • 在使用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
    var dt = new Date();
    var diffInMinutes = -dt.getTimezoneOffset();

    然后在服务器端,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不包含偏移量,因此没有转换。