在.Net中存储然后显示DateTimes的正确方法是什么?

时间:2013-04-08 20:09:01

标签: c# .net asp.net-mvc datetime

我想我可能已经住在山洞里一段时间了,因为DateTime的复杂性在今天才沉没。我已经阅读了一些文章,建议始终将DateTime作为UTC存储在数据库中,然后将它们显示为视图中的本地时间。

但是,然后,我点击文章说它不那么简单,你需要考虑“瞬间”并将用户输入的DateTime转换为UTC很难,因为TimeZone Id或使用ToUniversalTime()是不安全的,或者您可以JavaScript发布UTC DateTime并使用JS来显示当地时间,但如果我有Razor视图,该怎么办?一个DateTime模型属性?即使依赖ToLocalTime()也不能被视为安全。

我听说过Jon Skeet的Noda Time,我希望能解决这一切,尽管我知道他已经评论说它不完美。

那么人们在.Net中使用甚至非常简单的Web应用程序到底是什么?

是否有一个正确的示例,您可以提供或链接到哪些帖子,然后呈现时区同情的值?

似乎无知是幸福。

UPDATE:例如,用户拥有来自jQuery的DateTimePicker,他们选择事件的日期时间。该应用程序的用户是全球性的,所以如果他们选择美国东部时间上午10点,它应该在英国用户的下午6点出现在视图中。

2 个答案:

答案 0 :(得分:1)

让我们来看看我们拥有的所有技术: SQL Server(我认为你使用SQL Server,因为MS Stack) - DATETIME类型不存储时区偏移范围,所以这不会给我们提供其他选项,而不仅仅是将它们保留在UTC中。

.NET为您提供了在DateTime类型中使用时区进行操作的选项。因此,您可以从数据库加载值并以某种方式将其更改为用户时区。这是一个很好的问题,如何确定用户时区是什么?好的,所以如果用户在大小上注册 - 您可以使用“您的时区”之类的设置并将其存储给所有用户(网站的一个分支执行此操作,如Sharepoint),因此每次渲染视图时 - 您都使用此设置,使用正确的时区渲染视图。这个问题可能是如果你需要使用缓存 - 你需要根据用户时区进行缓存(不是最好的,呵呵)......

但是如果你有一些匿名的用户并且你没有关于他的信息怎么办?

我们来看看JavaScript吧。 JavaScript允许您使用时区进行操作。您可以在服务器上将所有与日期相关的字符串呈现为<date>2013-04-08T12:00:00Z</date>,这表示日期为UTC,在此onload之后您可以启动JS代码,该代码将在视图中找到所有date标记并转换它们浏览时区。 (我有一篇关于这个问题的文章Developing web application with time zones support,它有很多语法错误,对不起)。

所以,对我来说 - 正确的做法是将所有内容保留在UTC中,直到您不会向用户显示。只有View应该使用用户时区中的日期进行操作(在您的情况下,这应该只是JavaScript层),每次需要将带日期的数据发送到服务器时 - 您需要将此日期转换为UTC。每次从服务器获取日期 - 首先将它们转换为浏览器时区,然后将其显示给用户。

答案 1 :(得分:1)

我可以告诉你我是怎么做到的。 .NET有一个名为Kind的属性。我所做的是我的数据库中有一个名为UserTimeZome的字符串字段,在用户设置的某个位置,用户可以设置他或她的时区。您可以使用this code枚举下拉列表。

用户选择了他或她的时区后,我将DisplayName存储在我的数据库的UserTimeZone字段中。现在我有能力将UTC时间转换为当地时区,反之亦然。我可以使用ConvertTimeToUtc方法或ConvertTimeFromUtc方法。请务必通过创建新的DateTime并在DateTime构造函数上设置Kind来更新Kind Property。

与此同时,我可以将任何日期/时间转换为当地时间或UTC时间。现在如果您需要从javascript而不是C#中执行此操作,我会使用MomentJs。 MomentJs可以使用UTC functions转换为UTC和本地时间。

我希望这可以帮助你