将用户输入的确切日期从Javascript传递到.NET
在我们针对私立学校的ASP.NET MVC web应用程序中,用户可以输入日历事件的日期(以及其他事项,即家庭作业到期日),这些事件将使用学校的时区进行解释,时区可能不一定与他们自己的计算机相同(即,如果他们在另一个州度假时使用web应用程序) 我想直接传递日期,这样当我在服务器上收到日期时,我就可以准确地知道用户输入的值,并让服务器根据学校的时区将其转换为UTC时间 另一方面,我还希望服务器将已调整的日期传递给客户端,然后客户端应按原样显示这些日期。我不希望日期自动转换为计算机的时区,因为我希望所有日期都显示在学校的时区中 我们正在使用Json.NET对Json进行序列化/反序列化。我们当前的日期设置为:将用户输入的确切日期从Javascript传递到.NET,javascript,asp.net,json,datetime,nodatime,Javascript,Asp.net,Json,Datetime,Nodatime,在我们针对私立学校的ASP.NET MVC web应用程序中,用户可以输入日历事件的日期(以及其他事项,即家庭作业到期日),这些事件将使用学校的时区进行解释,时区可能不一定与他们自己的计算机相同(即,如果他们在另一个州度假时使用web应用程序) 我想直接传递日期,这样当我在服务器上收到日期时,我就可以准确地知道用户输入的值,并让服务器根据学校的时区将其转换为UTC时间 另一方面,我还希望服务器将已调整的日期传递给客户端,然后客户端应按原样显示这些日期。我不希望日期自动转换为计算机的时区,因为我希
serializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
也许我应该为DateTimeZoneHandling使用不同的选项
反序列化日期时的一个大问题是用户输入的实际日期不会被保留,除非它们与我们的服务器位于同一时区。因此,如果Pacific中的客户机输入的日期为下午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中学习了很多关于日期的好原则,但它们似乎都与我的情况不同:我不关心用户的时区是什么,我希望所有日期都显示在学校的时区中,并且将日期输入视为在学校时区的上下文中输入时间
在两个方向上,有没有一种简单的、非黑客的方式来做我想做的事情?(客户端向服务器发送日期,服务器向客户端发送日期)我不能100%确定我是否理解您的意思
但是如果您使用momentjs之类的东西,那么就不要在服务器上转换为时区。只需在任何地方使用UTC日期,然后告诉客户端javascript要使用的时区,然后使用矩将UTC时间转换为要显示的时区。根据您描述的场景,听起来最简单的方法是只传递不合格的日期和时间值,而不是本地或UTC
- 在服务器上,将
值与DateTime
种类一起使用,或使用Noda-Time的Unspecified
LocalDateTime
- 将JSON.Net的日期格式处理保留为默认值,即
和DateFormatHandling.IsoDateFormat
。只要注意正确的DateTimeZoneHandling.RoundtripKind
,您几乎不需要修改它们Kind
- 如果要直接序列化Noda时间类型,请确保使用
连接NodaTime.Serialization.JsonNet库,如前所述ConfigureForNodaTime
- 如果要直接序列化Noda时间类型,请确保使用
- 通过连线,数据应该看起来像“eventTime”:“2016-03-01T10:00:00”。不要包含
,因为您没有发送UTC。也不要包含偏移量Z
- 在客户端,不要使用
对象。它总是在当地时区工作。相反,考虑使用.< /P>Date
- 目前没有“未指定”模式,但您可以通过使用UTC模式来伪造它,即使该值实际上不是UTC格式,这对于格式化仍然很有效。调用
。不要使用moment.utc(您的值)
,因为它将处于本地模式,并将与时刻(yourvalue)
对象一样呈现本地时区的DST行为日期
- 或者,您真的可以像RobG在评论中建议的那样使用字符串。您只需要自己在用户输入和wire format之间解析和格式化它们。有些人可能会觉得这很容易,有些人更愿意让图书馆来做
- 目前没有“未指定”模式,但您可以通过使用UTC模式来伪造它,即使该值实际上不是UTC格式,这对于格式化仍然很有效。调用
DateTimeOffset
可能更合适
还要认识到,您可以在客户端完成这项工作,使用类似“时刻时区”的功能。但是,对于这种特殊情况,这可能不是必需的。将所有日期保留为字符串,不要使用日期对象。如果您对所有内容都只使用UTC方法,则可以使用日期对象,但这可能会很费劲。只需发送字符串并编写一些简单的重新格式化函数(例如,将2016-02-24转换为2016年2月24日非常简单)。顺便说一句,只需将时区偏移量添加到日期即可实现UTC,因此:
date.setMinutes(date.getMinutes()+date.getTimezoneOffset())
将意味着本地值将与以前的UTC值相同。@RobG-添加您建议的偏移分钟数基本上与他显示的将基于UTC的字段传递到预期本地时间的构造函数中的方式相同。两者都是根本错误的,因为它们只是改变了时刻