通过视图模型接收 DateTime 输入的最佳实践是啥?

Posted

技术标签:

【中文标题】通过视图模型接收 DateTime 输入的最佳实践是啥?【英文标题】:What's the best practice about receiving DateTime input through the View Models?通过视图模型接收 DateTime 输入的最佳实践是什么? 【发布时间】:2019-08-11 14:12:18 【问题描述】:

我有一个视图模型,其中一个属性是DateTime。我想允许请求者在他们想要的任何时区发送 DateTime。最后,我想将该日期时间转换为 UTC,如果时区信息没有随日期到达,则假设它是 UTC。

或者,我可以将发布的 DateTime 限制为 UTC 或至少包含时区信息的内容。

我的后端使用 UTC 格式的所有日期,以 UTC 格式返回它们,这也是它的保存方式。这个问题是关于接收“客户”输入以及接受日期并将其转换为或确保其为 UTC 的最佳做法。

这就是我现在拥有的

public class MyViewModel

    /// <summary>
    /// Start date, in UTC.
    /// </summary>
    [Required]
    [DataType(DataType.Date)]
    public DateTime StartDate  get; set; 

在控制器中:

// Convert to UTC
model.StartDate = model.StartDate.ToUniversalTime();

我想我也可以通过添加构造函数在视图模型本身中做到这一点。

通过视图模型接收DateTime 输入的最佳做法是什么?最终,我想确保我收到的是 UTC。

【问题讨论】:

这真的取决于一个项目一个项目的基础。如果您的方法始终如一,我已经看到它以各种方式完成并且您正在做的事情很好。 全局设置DateTimeZoneHandling.Utc。可能是你需要的。考虑到 JSON 日期时间字符串中的任何显式时区偏移,它在反序列化期间转换为 UTC。 @dbc “考虑到 JSON 日期时间字符串中的任何显式时区偏移” - 意思是如果字符串中有时区,它不会覆盖它,对吧? 意味着它将使用字符串中的时区转换为UTC,同时考虑到提供的时区。请参阅 Can you tell JSON.Net to serialize DateTime as Utc even if unspecified? 或者,我想您可以在模型中创建一个合成的 DateTimeOffset 属性,然后在 setter 中自己进行转换。 马上要说明的一点:DateTime.ToUniversalTime 应该永远在网络应用程序中使用。它将从服务器的本地时区转换为UTC。 【参考方案1】:

如果您的应用程序要在多个时区中使用,我建议将 UTC 日期时间对象保存在数据库中。

将此 UTC 日期时间对象转换为本地日期时间的常见做法。

输入

API 应采用 ISO 8601 格式作为输入 as mentioned in this blog。

更喜欢 ISO 8601 (yyyy-MM-dd'T'HH:mm:ssZ),因为它是 人类可读并具有指定的时区。如果没有歧义 纪元以秒或毫秒为单位。 ISO 8601 字符串被编码 以一种能够实现不错的字符串排序和比较的方式。

输出

相信你想知道web api应该如何返回DateTime对象。

在我看来,RESTful API 应该独立于时区,它应该以 UTC 格式返回日期。

调用此 API 的手机应用程序/桌面应用程序/网络应用程序应负责以正确的时区格式显示日期。

但是,正如前面在 cmets 中所述,此决定是由您的应用程序设计驱动的。

我希望这会有所帮助。

【讨论】:

是的,我已经将日期保存为 UTC,因此我也总是返回 UTC。我同意,应由消费者在正确的时区显示。问题是关于输入。确保日期为 UTC 的最佳做法是什么。

以上是关于通过视图模型接收 DateTime 输入的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用视图模型中的属性值实现方法的最佳实践是啥?

使用 Core Data 在视图中引用模型对象的最佳实践是啥?

MVC - 数据计算最佳实践 - 视图模型与控制器

最佳实践 - 从视图访问域对象列表?

iOS - 为帖子 + 评论数据模型设置视图控制器的最佳实践是啥?

软件工程实践感悟