在我们用于私立学校的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日期的好原则,但它们似乎与我的情况不同:我不关心用户的时区是什么,我希望所有日期都显示在学校的时区,并将日期输入视为在学校时区的背景下进入时间。
在两个方向上,是否有一种简单且非黑客的方式来做我正在尝试做的事情? (客户端向服务器发送日期,服务器向客户端发送日期)
答案 0 :(得分:3)
从您描述的场景中,听起来最简单的事情就是传递无限制的日期和时间值,而不是本地或UTC。
在服务器上,使用DateTime
类型的Unspecified
值,或使用Noda Time' LocalDateTime
。
将JSON.Net的日期格式处理保留为默认值DateFormatHandling.IsoDateFormat
和DateTimeZoneHandling.RoundtripKind
。只要您正确注意Kind
,就很少需要修改它们。
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时间转换为您想要显示的时区。