我有一个网站托管在与使用该应用程序的用户不同的时区。除此之外,用户还可以拥有特定的时区。我想知道其他 SO 用户和应用程序如何处理这个问题?最明显的部分是在数据库内部,日期/时间以 UTC 存储。在服务器上时,所有日期/时间都应以 UTC 格式处理。然而,我看到了我正在努力克服的三个问题:
-
获取 UTC 中的当前时间(使用以下命令可以轻松解决)DateTime.UtcNow
).
-
从数据库中提取日期/时间并将其显示给用户。有潜在的lots在不同视图上打印日期的调用。我正在考虑视图和控制器之间的某个层可以解决这个问题。或者有一个自定义扩展方法DateTime
(见下文)。主要的缺点是every在视图中使用日期时间的位置,必须调用扩展方法!
这也会增加使用类似的东西的难度JsonResult
。你不能再轻易打电话Json(myEnumerable)
,它必须是Json(myEnumerable.Select(transformAllDates))
。也许 AutoMapper 在这种情况下可以提供帮助?
-
获取用户的输入(本地至 UTC)。例如,发布带有日期的表单需要先将日期转换为 UTC。第一个想到的就是创建自定义ModelBinder
.
这是我想在视图中使用的扩展:
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);
}
}
我认为考虑到许多应用程序现在都是基于云的,其中服务器的本地时间可能与预期的时区有很大不同,处理时区将是一件很常见的事情。
这个问题之前已经被优雅地解决了吗?我有什么遗漏的吗?非常感谢想法和想法。
EDIT:为了消除一些混乱,我想添加一些更多细节。现在的问题不是how将UTC时间存储在数据库中,更多的是从UTC->本地和本地->UTC的过程。正如 @Max Zerbini 指出的那样,将 UTC->Local 代码放入视图中显然是明智的,但使用的是DateTimeExtensions
真的是答案吗?当从用户那里获取输入时,接受日期作为用户的本地时间(因为这就是 JS 将使用的)然后使用ModelBinder
转换为UTC?用户的时区存储在数据库中并且可以轻松检索。
并不是说这是一个建议,它更多的是共享一个范式,但最重要的是攻击性的我见过的在 Web 应用程序中处理时区信息的方式(这并非 ASP.NET MVC 独有的)如下:
到目前为止,票价相当标准,但这就是事情变得“有趣”的地方。
-
如果您必须接受来自客户端的日期,请使用 javascript 确保您发布到服务器的数据采用 UTC。客户端知道它所在的时区,因此它可以以合理的精度将时间转换为 UTC。
-
渲染视图时,他们使用 HTML5<time>
元素,它们永远不会直接在 ViewModel 中渲染日期时间。它的实施如下HtmlHelper
扩展名,类似Html.Time(Model.when)
。它会呈现<time datetime='[utctime]' data-date-format='[datetimeformat]'></time>
.
然后他们会使用 JavaScript 将 UTC 时间转换为客户端本地时间。该脚本会找到所有<time>
元素并使用date-format
data 属性来格式化日期并填充元素的内容。
这样,他们就不必跟踪、存储或管理客户的时区。服务器不关心客户端所在的时区,也不必进行任何时区转换。它只是输出 UTC 并让客户端将其转换为合理的值。这对于浏览器来说很容易,因为它知道它所在的时区。如果客户端更改了他/她的时区,Web 应用程序将自动更新自身。他们存储的唯一内容是用户区域设置的日期时间格式字符串。
我并不是说这是最好的方法,但这是一种我以前从未见过的不同方法。也许你会从中收集到一些有趣的想法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)