将用户输入的确切日期从Javascript传递到.NET

时间:2016-02-23 01:03:09

标签: javascript asp.net json datetime nodatime

在我们用于私立学校的ASP.NET MVC Web应用程序中,用户可以输入日历事件(以及其他内容,即家庭作业截止日期)的日期,这些日期应使用学校的时间进行解释区域,可能不一定与他们自己的计算机相同(即,如果他们在另一个州度假时使用网络应用程序)。

我想直接传递日期,这样当我在服务器上收到日期时,我就可以确切知道用​​户输入了什么值,并让服务器根据学校的时间将其转换为UTC时间区。

另一方面,我还希望服务器将已调整的日期传递给客户端,然后客户端应按原样显示这些日期。我不希望日期自动转换为计算机的时区,因为我希望所有日期都显示在学校的时区。

我们正在使用Json.NET来序列化/反序列化JSON。我们目前的日期设置是:

serializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;

也许我应该为DateTimeZoneHandling使用不同的选项......?

反序列化日期时的一个大问题是用户输入的实际日期未保留,除非它们与我们的服务器位于同一时区。因此,如果太平洋地区的客户输入时间为下午4:00的日期,那么服务器(在中部时间)会将其视为下午6:00,这是正确的,因为它们代表UTC的相同时间,但是我真的想要知道用户在下午4:00输入,并注意确定服务器端实际代表的UTC时间。

我在服务器上使用NodaTime来处理用户输入时间到实际UTC时间的转换,以便存储在数据库中。

我在javascript中的当前解决方案,当从服务器接收日期时,将返回转换为UTC,以便我有服务器通过的实际日期。这部分感觉很糟糕。

    function convertToUTCDate(date) {
        var utcDate = new Date(
            date.getUTCFullYear(),
            date.getUTCMonth(),
            date.getUTCDate(),
            date.getUTCHours(),
            date.getUTCMinutes(),
            date.getUTCSeconds()
        );

        return utcDate;
    }

我查看了很多StackOverflow问题,我在PluralSight中完成了Matt Johnson的日期和时间基础课程。我已经学习了很多关于javascript和.NET日期的好原则,但它们似乎与我的情况不同:我不关心用户的时区是什么,我希望所有日期都显示在学校的时区,并将日期输入视为在学校时区的背景下进入时间。

在两个方向上,是否有一种简单且非黑客的方式来做我正在尝试做的事情? (客户端向服务器发送日期,服务器向客户端发送日期)

2 个答案:

答案 0 :(得分:3)

从您描述的场景中,听起来最简单的事情就是传递无限制的日期和时间值,而不是本地或UTC。

  • 在服务器上,使用DateTime类型的Unspecified值,或使用Noda Time' LocalDateTime

  • 将JSON.Net的日期格式处理保留为默认值DateFormatHandling.IsoDateFormatDateTimeZoneHandling.RoundtripKind。只要您正确注意Kind,就很少需要修改它们。

    • 如果您直接序列化Noda时间类型,请务必使用ConfigureForNodaTime连接NodaTime.Serialization.JsonNet库,如in the user guide所述。
  • 通过网络,数据应该看起来像"eventTime" : "2016-03-01T10:00:00"。不要包含Z,因为您没有发送UTC。不要包括偏移量。

  • 在客户端,不要使用Date对象。它总是在当地时区工作。相反,请考虑使用moment.js

    • 没有"未指定"模式,但您可以使用UTC模式伪造它,即使该值实际上不是UTC,这仍然适用于格式化。致电moment.utc(yourvalue)。不要使用moment(yourvalue),因为它将处于本地模式,并且将像Date对象一样承担本地时区的DST行为。

    • 或者,你真的可以只使用RobG在评论中建议的字符串。您只需要自己在用户输入和线路格式之间进行解析和格式化。有些人可能觉得这很容易,有些人更喜欢让图书馆这样做。

最后,请注意我根据您描述的方案中的许多假设来提出此建议。它可能是也可能不是理想的,如果有其他用例您没有解释。例如,如果您通过此API向某个第三方发送相同的值,则包含偏移量序列化的DateTimeOffset可能更合适。

同时认识到可以在所有客户端执行此操作,使用类似时刻的方式。然而,对于这种特殊情况,这可能不是必需的。

答案 1 :(得分:0)

不是100%肯定我得到你说的话。

但是如果你使用像momentjs这样的东西,那么就不要转换到服务器上的时区。只需在任何地方使用UTC日期,然后告诉客户端javascript使用的时区是什么,然后使用时刻将utc时间转换为您想要显示的时区。