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

Passing exact date entered by user from Javascript to .NET

本文关键字:Javascript NET 日期 输入 用户      更新时间:2023-09-26

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

我只想从字面上传递日期,这样当我在服务器上收到日期时,我可以确切地知道用户输入的值,并让服务器负责根据学校的时区将其转换为 UTC 时间。

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

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

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

也许我应该使用不同的选项来处理日期时区处理...?

反序列化日期时最大的问题是用户输入的实际日期不会保留,除非它们与我们的服务器位于同一时区。因此,如果太平洋地区的客户端输入的时间是下午 4:00 的日期,那么服务器(中部时间)将看到它为 6:00 PM,这是正确的,因为它们以 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 问题,也看过 Matt Johnson 在 PluralSight 中的日期和时间基础课程。我已经学到了很多关于 javascript 和 .NET 中日期的好原则,但它们似乎都与我的情况不同:我不在乎用户的时区是什么,我希望所有日期都以学校的时区显示,并且还将日期输入视为在学校时区的上下文中输入时间。

有没有一种简单且非黑客的方法可以在两个方向上完成我想要做的事情?(客户端向服务器发送日期,服务器向客户端发送日期)

从您描述的场景中,听起来最简单的方法是只传递不合格的日期和时间值,而不是本地或 UTC。

  • 在服务器上,将DateTime值与Unspecified一起使用,或使用野田时间的LocalDateTime

  • 留下 JSON。Net的日期格式处理默认值为DateFormatHandling.IsoDateFormatDateTimeZoneHandling.RoundtripKind。 您很少需要修改这些,只要您注意正确Kind即可。

    • 如果要直接序列化 Noda Time 类型,请务必使用 ConfigureForNodaTime 连接 NodaTime.Serialization.JsonNet 库,如用户指南中所述。
  • 通过网络,数据应看起来像"eventTime" : "2016-03-01T10:00:00"。 不要包含Z,因为您不会发送UTC。 也不包括偏移量。

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

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

    • 或者,您真的可以按照 RobG 在评论中的建议使用字符串。 您只需要在用户输入和自己有线格式化之间解析和格式化它们。 有些人可能会觉得这很容易,而另一些人则更喜欢让图书馆来做。

最后,认识到我是根据您描述的场景中的许多假设提出此建议的。 如果还有其他您没有解释的用例,它可能很理想,也可能不理想。 例如,如果要通过此 API 将相同的值发送给某些第三方,则包含偏移量的序列化DateTimeOffset可能更合适。

还要认识到,您可以使用诸如时刻时区之类的东西在客户端执行此操作。 但是,对于这种特殊情况,这可能不是必需的。

不是 100% 确定我明白你在说什么。

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