如何优雅地处理时区 [英] How to elegantly deal with timezones

查看:258
本文介绍了如何优雅地处理时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个托管在一个不同的时区比使用该应用程序的用户的一个网站。除了这一点,用户可以有一个特定的时区。我不知道如何等,使用户和应用程序处理这个?最明显的部分就是数据库里面,日期/时间存储在UTC。当在服务器上,所有的日期/时间应在UTC处理。但是,我看到,我努力克服三个问题:

I have a website that is hosted in a different timezone than the users using the application. In addition to this, users can have a specific timezone. I was wondering how other SO users and applications approach this? The most obvious part is that inside the DB, date/times are stored in UTC. When on the server, all date/times should be dealt with in UTC. However, I see three problems that I'm trying to overcome:

  1. 获取当前UTC时间(与迎刃而解 DateTime.UtcNow )。

拉日期/从数据库并显示这些用户次。有可能的许多的调用打印日期不同的看法。我在想一些层的视图,并可能会解决这个问题的控制器之间。或者有关于的DateTime 自定义扩展方法(见下文)。主要的缺点是,在的使用在一个视图中的日期时间的位置,扩展方法必须被调用!

Pulling date/times from the database and displaying these to the user. There are potentially lots of calls to print dates on different views. I was thinking of some layer in between the view and the controllers that could solve this issue. Or having a custom extension method on DateTime (see below). The major down side is that at every location of using a datetime in a view, the extension method must be called!

这也将增加难度,使用类似 JsonResult 。你再也不能方便地调用 JSON(myEnumerable),它必须是 JSON(myEnumerable.Select(transformAllDates))。也许AutoMapper可能在这种情况下帮助?

This would also add difficulty to using something like the JsonResult. You could no longer easily call Json(myEnumerable), it would have to be Json(myEnumerable.Select(transformAllDates)). Maybe AutoMapper could help in this situation?

从用户(本地为UTC)获得输入。例如,对于一个日发布一个形式将需要前的时间转换为UTC。我想到的第一件事是创建一个自定义的 ModelBinder的

Getting input from the user (Local to UTC). For example, POSTing a form with a date would require converting the date to UTC before. The first thing that comes to mind is creating a custom ModelBinder.

下面是我想用在视图中的扩展:

Here's the extensions that I thought of using in the views:

public static class DateTimeExtensions
{
    public static DateTime UtcToLocal(this DateTime source, 
        TimeZoneInfo localTimeZone)
    {
        return TimeZoneInfo.ConvertTimeFromUtc(source, localTimeZone);
    }

    public static DateTime LocalToUtc(this DateTime source, 
        TimeZoneInfo localTimeZone)
    {
        source = DateTime.SpecifyKind(source, DateTimeKind.Unspecified);
        return TimeZoneInfo.ConvertTimeToUtc(source, localTimeZone);
    }
}

我会认为,处理时区将是这样一个平常的事情考虑了很多应用程序现在基于云的服务器的本地时间可能比预期的时间段太大的不同。

I would think that dealing with timezones would be such a common thing considering a lot of applications are now cloud-based where the server's local time could be much different than the expected time zone.

这已经被优雅的解决过吗?有什么我失踪?思路和想法是多少AP preciated。

Has this been elegantly solved before? Is there anything that I'm missing? Ideas and thoughts are much appreciated.

编辑:要清除一些混乱我想补充一些更多的细节。这个问题现在是不是的如何的存储UTC时间在数据库中,它更多的是从UTC->本地和局域> UTC去的过程。由于@Max Zerbini指出,这显然是聪明的把UTC->本地code在视图中,但使用的是 DateTimeExtensions 真正的答案是什么?当从用户获得输入,它是有意义的接受日期为用户的本地时间(因为什么JS将使用的),然后使用 ModelBinder的转换到UTC ?用户的时区被存储在DB,并很容易地检索

To clear some confusion I thought add some more details. The issue right now isn't how to store UTC times in the db, it's more about the process of going from UTC->Local and Local->UTC. As @Max Zerbini points out, it's obviously smart to put the UTC->Local code in the view, but is using the DateTimeExtensions really the answer? When getting input from the user, does it make sense to accept dates as the user's local time (since that's what JS would be using) and then use a ModelBinder to transform to UTC? The user's timezone is stored in the DB and is easily retrieved.

推荐答案

不,这是一个建议,它更多地分享一个范例,但大多数的侵略性的我看到处理时区的方式在Web应用程序的信息(这是不是唯一到ASP.NET MVC)是如下:

Not that this is a recommendation, its more sharing of a paradigm, but the most agressive way I've seen of handling timezone information in a web app (which is not exclusive to ASP.NET MVC) was the following:

  • 所有日期时间在服务器上为UTC。 这意味着使用,就像你说的, DateTime.UtcNow

  • All date times on the server are UTC. That means using, like you said, DateTime.UtcNow.

尽量不信任传递日期的服务器尽可能少的客户端。例如,如果你需要的现在,不创建客户端上的一个日期,然后将它传递给服务器。无论是建立在你得到一个日期,并把它传递到视图模型或POST做 DateTime.UtcNow

Try to not trust the client passing dates to the server as little as possible. For example, if you need "now", don't create a date on the client and then pass it to the server. Either create a date in your GET and pass it to the ViewModel or on POST do DateTime.UtcNow.

到目前为止,pretty的标准收费,但是这是事情变得有趣。

So far, pretty standard fare, but this is where things get 'interesting'.

  • 如果你必须接受来自客户端的日期,然后使用JavaScript来确保你正在发布到服务器的数据是UTC。客户端知道它是什么时区,所以它可以相当准确地转换成时间UTC。

  • If you have to accept a date from the client, then use javascript to make sure the data that you are posting to the server is in UTC. The client knows what timezone it is in, so it can with reasonable accuracy convert times into UTC.

在渲染的看法,他们使用了HTML5 <时间> 元素,他们绝不会直接在视图模型渲染日期时间。它实现为的HtmlHelper 扩展,像 Html.Time(Model.when)。这将使<时间日期时间=[utctime]数据日期格式​​='[datetimeformat]'>< /时间>

When rendering views, they were using the HTML5 <time> element, they would never render datetimes directly in the ViewModel. It was implemented as as HtmlHelper extension, something like Html.Time(Model.when). It would render <time datetime='[utctime]' data-date-format='[datetimeformat]'></time>.

然后,他们会使用JavaScript翻译UTC时间到客户端的本地时间。该脚本会发现所有的&LT;时间&gt; 元素,并使用日期格式 data属性来格式化日期和填充元件的内容。

Then they would use javascript to translate UTC time into the clients local time. The script would find all the <time> elements and use the date-format data property to format the date and populate the contents of the element.

这样,他们从未有过跟踪,存储或管理的客户端时区。服务器不关心什么时区客户端是,也没有做任何时区转换。它只是吐出UTC,让客户将其转换成的东西,是合理的。这是从浏览器容易,因为它知道它是在什么时区。如果客户机改变了他/她的时区,网络应用程序将自动更新。它们存储的是日期时间格式字符串用户的区域设置的唯一的事。

This way they never had to keep track of, store, or manage a clients timezone. The server didn't care what timezone the client was in, nor had to do any timezone translations. It simply spit out UTC and let the client convert that into something that was reasonable. Which is easy from the browser, because it knows what timezone it is in. If the client changed his/her timezone, the web application would automatically update itself. The only thing that they stored were the datetime format string for the locale of the user.

我并不是说这是最好的办法,但它是一个不同的,我从来没有见过的。也许你会搜集一些有趣的想法,从它。

I'm not saying it was the best approach, but it was a different one that I had not seen before. Maybe you'll glean some interesting ideas from it.

这篇关于如何优雅地处理时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆