从查询字符串中获取UTC DateTime

时间:2017-12-11 16:28:56

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

假设我们有行动:

[HttpGet]
public Task<IActionResult> Foo(DateTime date)
{
    var utc = date.ToUniversalTime();
}

默认情况下,MVC框架似乎将UTC DateTime转换为Local(中间件中的某个位置)。如何关闭此行为并摆脱其他转换?

UPD:

Chrome开发者console(网络选项卡)显示我这样的查询参数: date:2017-12-01T00:00:00.000Z

但在控制器中我看到: {01/12/2017 03:00:00}

1 个答案:

答案 0 :(得分:1)

如果需要准确的基于时区的时间,则不应使用

DateTime。这就是DateTimeOffset存在的原因。默认情况下,DateTime.KindDateTimeKind.Unspecified。换句话说,在发布后,它取决于你,以确定它应被解释为什么。问题是你真的只能假设DateTimeKind.Utc,因为这是唯一可以正确解释为DateTime的东西。发布用户的本地时间会使您陷入困境,因为DateTimeKind.Local实际上意味着服务器的本地时间,这通常不会与客户端相同[&1;第

但是,即使在HTML5中,使用时区发布完整日期时间实际上也是不可能的。虽然存在datetimedatetime-local等输入类型,但它们并未在任何主要浏览器中实现。如果您想发布带有时间和时区的日期,那么您实际上需要在视图模型上使用三个属性:

public DateTime Date { get; set; }
public TimeSpan Time { get; set; }
public string TimeZone { get; set; }

TimeZone属性假设您使用由TimeZoneInfo.GetSystemTimeZones()的值组成的下拉列表。如果您想使用不同的设置,则需要某种方式来映射/从这些值映射,因为您必须使用C#来获取偏移量。但是,您可以简单地允许用户发布偏移量,但这对用户不太友好,对某些用户来说可能很难。特别是,他们不仅需要了解概念&#34;偏离UTC&#34;意味着,但也考虑到夏令时的当前状态,并根据实际日期调整该偏移。

无论如何,在{{1}的情况下,每个属性都可以轻松映射到输入类型:date / timeselect / time取决于您是使用下拉列表还是手动偏移条目。它们也可以通过模型绑定器轻松映射回您的视图模型。然后,您只需要根据该信息创建TimeZone,这就是您实际在实体类中保留的信息。

DateTimeOffset