在.Net中处理日期时间与时区的最佳方法

4

最近我一直在处理.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的跳跃,但是将偏移量传递到SP或类似的DB中不会正确处理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而另一天不处于DST而出现偏差。例如,2012年3月10日2:00:00 EST是2012年3月9日20:00:00 UTC,但2012年3月13日2:00:00 EST是2012年3月12日19:00:00 UTC。基本上,分别为-4和-5的偏移量。因此,您要将哪个偏移量传递到SP中以将UTC转换为本地时间?无论哪种方式都是错误的。 - aBetterGamer
我认为你需要提供更多关于时间如何使用的信息。如果它是一个时间戳,那么数据库的本地时间戳格式(几乎肯定)是答案(可能是UTC)。如果只是为了向用户显示他们上次登录的时间,那么本地时间字符串可能是合适的。 - MZB
1个回答

1
你当前的方法并不是“错误”的,但如果跟踪偏移量会更好。
当你谈论偏移量时,似乎认为它们与时区相关。但请注意,大多数时区有两个不同的偏移量,一个用于标准时间,另一个用于夏令时。Microsoft的时区ID仍然在字符串中包含“标准”一词,因此这可能是混淆的一部分。但你正在使用的TimeZoneInfo确实跟踪标准和夏令时偏移量。
你需要将偏移量与每个单独的日期和时间关联起来。你可以使用.Net中的DateTimeOffset类和SQL Server中的datetimeoffset数据类型来实现这一点。
如果你始终如一地使用这些,那么就不需要进行UTC转换了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接