c# - 存储用户的时区首选项

标签 c# .net timezone

我在这里的要求是相当标准的;我需要允许用户选择他们当前的TimeZone并将其保存到他们的帐户中。然后,我将使用该值将存储的DateTime值转换为本地化时间。

我当前的想法是,我将允许用户从列表中选择一个.NET TimeZoneInfo.Id(保留在数据库中,以便进行更友好的描述,但使用TimeZoneInfo.GetSystemTimeZones()构造)-然后,我将使用该值使用TimeZoneInfo返回相关的TimeZoneInfo.FindSystemTimeZoneById()实例并执行转换。我在这里看到的主要问题是TimeZoneInfo.Id是注册表中保存的一个值,而不是“标准” ID(例如,与Olson相比)。因此,服务器更新/迁移可能会完全使存储的ID无效并使转换中断。

简而言之-这种方法有效/安全吗?如果不是,是否有更好的方法来存储用户的时区首选项,同时还处理夏时制等,而又不增加大量逻辑?

最佳答案

我刚刚发现了这个古老的 Unresolved 问题,因此以为我应该对它进行刺探。

In short - is this approach valid/safe?



这完全取决于您打算如何处理它们。

如果仅在服务器端代码中使用它,则可以。您只需存储时区的Id,然后向用户显示相应的DisplayNameFindSystemTimeZoneByIdGetSystemTimeZones对此完全有效。

请记住,尽管Id值始终相同,但DisplayName属性将根据运行代码的Windows操作系统的语言而有所不同。该实现不了解区域性,因此仅在.Net中设置不同的目标区域性就不会更改DisplayName字符串。

Microsoft Windows时区数据库中的记录相当稳定,并通过Windows Update进行更新。一些信息来自注册表,但是本地化的资源字符串来自tzres.dll。当然,TimeZoneInfo和相关类对您隐藏了所有这些内容。

但是,如果要将这些时区Id值传递给其他系统,请当心。 Windows的早期版本有一些变体。例如,我知道以前所有显示名称都用“GMT”表示,现在更正确地用“UTC”表示。 Id的值是相同的,但谁能确切知道还有哪些不一致。特别是如果目标计算机没有收到与您拥有的Windows Updates相同的一组Windows Updates。顺便说一句-更新宣布here

您还应该了解有关Windows时区数据库的一些知识:
  • 每个日历年不能表示两个以上的DST转换。例如-in 2010, Cairo, Egypt had four transitions。微软发布了a hotfix,但这仅做出了一个折衷的更正,而不是历史上准确的一个。还有其他具有此类历史变化的区域,无法正确表示。
  • 在Windows XP/2003和Vista/2008之间进行了一些更改。关于此here确实有一些很好的信息,以及有关如何使用注册表的许多详细信息。
  • 微软是拥有自己时区数据库的唯一主要公司。世界其他地方使用IANA/Olson database。这导致互操作性问题。我在the timezone tag wiki中对此做了不错的记录。

  • 您还应该知道TimeZoneInfoDateTimeDateTimeOffset类有着千丝万缕的联系。这些有他们自己的一套怪癖。 DateTimeOffset有点可用,但是DateTime充满了细微差别。读:

    Jon Skeet的
  • What's wrong with DateTime anyway?
  • 马特·约翰逊(我)的
  • The case against DateTime.Now

  • .Net中日期和时间的更好解决方案是使用NodaTime。该库实现了两个时区数据库,包括它们之间的CLDR映射。它还提供了更安全的API,不会让您遇到麻烦。可能需要重新学习一点,但是在您不了解之前,您将使用LocalDateTimeZonedDateTimeOffsetDateTimeInstant这样的类。

    您仍然存在时区数据库经常更新的问题,因为我们将计时规则留给政客。但是the TZDB folks很好地保持了数据库的历史准确性,并在区域名称更改时提供别名/链接。您可以看到tz名称here的列表。

    另外,如果您使用NodaTime,则可以选择保留编译到发行版中的TZDB副本,也可以将自己的副本随应用程序一起提供。您可以(理论上)编写自己的代码以从IANA下拉最新版本并保持应用程序更新-所有这些都无需依赖主机操作系统。

    关于c# - 存储用户的时区首选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12231422/

    相关文章:

    c# - 在 C# 中运行并显示富文本文件中的 exe 文件

    .net - ODP.NET程序编译

    .net - 在 .Net 和 COM 程序集之间传递数据的性能

    java - android: TimeZone.getDefault() 返回 EST,而不是 EDT

    php时间偏移mysql实时时间

    android - Android设备错误地解析了服务器中的日期时间

    c# - 使用预定义图像集创建头像

    c# - azure : data storage with append

    c# - 检查存储过程是否返回值

    javascript - Uncaught Error : [$http:badreq] Http request configuration url must be a string (AngularJS)