【问题标题】:Best way to handle date times with respect to time zones in .Net在.Net中处理与时区有关的日期时间的最佳方法
【发布时间】:2012-10-09 01:03:38
【问题描述】:

我最近在 .net 中的时区感知 Web 应用程序中处理时区问题。我想出了以下处理时区的解决方案。

我的解决方案是:

  • 让用户配置文件存储他们所在的时区。
  • 在 Web 服务器上进行与 UTC 的所有转换。
  • 将数据库中的日期存储为 UTC。

我的问题是:

  1. 你们认为这是 .net 中最好的方法吗?
  2. 在 UTC 中使用 datetime2 是否足够好,或者我应该将客户时间存储在 数据库中的偏移量(基本上是 10-10-2012 4:00:00 vs 10-10-2012 00:00:00 4:00)?
  3. 顺便说一句,你们中的一些人可能会注意到,虽然跨 DST 的跳转是在服务器代码中处理的,但将偏移量传递给 DB 上的 SP 等将无法正确处理 DST。对此有何想法?

这是时间转换的示例代码。

    private TimeZoneInfo GetTimeZoneInfo()
    {
        var timeZone = TimeZoneDropdown.SelectedValue;

        switch (timeZone)
        {
            case "Eastern":
                return TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            case "Central":
                return TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
            case "Mountain":
                return TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            case "Pacific":
                return TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
            case "Alaskan":
                return TimeZoneInfo.FindSystemTimeZoneById("Alaskan Standard Time");
        }

        return TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
    }

    public DateTime ConvertLocalDateTimeToUtc(DateTime dateTime)
    {
        var timeZone = GetTimeZoneInfo();

        return TimeZoneInfo.ConvertTimeToUtc(DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified), timeZone);
    }

    public DateTime ConvertUtcToLocalDateTime(DateTime dateTime)
    {
        var timeZone = GetTimeZoneInfo();

        return TimeZoneInfo.ConvertTimeFromUtc(DateTime.SpecifyKind(dateTime, DateTimeKind.Utc), timeZone);
    }

【问题讨论】:

  • 在数据库中将日期时间存储为 UTC 有一个缺点。您如何在数据库端考虑 DST?没有办法将 DateTime 或 DateTime2 转换为相对于时区和 DST 的用户本地时间。如果你通过了一个偏移量,那么你仍然可能因为一天在 DST 而另一天不在。示例 3/10/2012 2:00:00 EST 是 3/09/2012 20:00:00 UTC 但 3/13/2012 2:00:00 EST 是 3/12/2012 19:00:00 UTC。基本上分别是-4和-5的偏移量。那么您将哪个偏移量传递给您的 SP -4 或 -5 以将 UTC 转换为本地?无论哪种方式都是错误的。
  • 我认为您需要提供更多关于时间将如何使用的信息。如果它是时间戳,那么数据库的本机时间戳格式(几乎可以肯定)是答案(可能是 UTC)。如果只是为了向用户显示他们上次登录的时间,那么本地时间字符串可能是合适的。

标签: .net sql-server timezone timezone-offset


【解决方案1】:

您当前的方法没有错误,但您可以通过跟踪偏移量做得更好。

当您谈论偏移时,您似乎将它们与时区相关联。但是要意识到大多数时区有两种不同的偏移量,一种是标准时间,一种是日光时间。两者的 Microsoft 时区 ID 在字符串中仍有“标准”,因此这可能是混淆的一部分。但是您正在使用的 TimeZoneInfo 确实在跟踪标准和日光偏移量。

您需要将偏移量与每个单独的日期和时间相关联。您可以使用 .Net 中的 DateTimeOffset 类和 SQL Server 中的 datetimeoffset 数据类型来实现。

如果您始终如一地使用这些,则无需在 UTC 之间进行转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 2011-06-30
    • 2011-04-17
    • 2011-04-16
    相关资源
    最近更新 更多