将用户输入的确切日期从 Javascript 传递到 .NET
Passing exact date entered by user from Javascript to .NET
在我们的 ASP.NET 私立学校 MVC 网络应用程序中,用户可以输入日历事件的日期(以及其他内容,即家庭作业截止日期),这些日期将使用 学校的 时区,不一定与他们自己的计算机相同(即,如果他们在另一个州度假时使用网络应用程序)。
我只想按字面意思传递日期,这样当我在服务器上接收到它们时,我可以确切地知道用户输入的值是什么,并让服务器根据学校的时区。
另一方面,我也希望服务器将已调整的日期传递给客户端,然后客户端应按原样显示这些日期。我不希望日期自动转换为计算机时区,因为我希望所有日期都显示为学校时区。
我们将 Json.NET 用于 serializing/deserializing JSON。我们当前的日期设置是:
serializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
也许我应该为 DateTimeZoneHandling 使用不同的选项...?
反序列化日期的最大问题是用户输入的实际日期不会被保留,除非它们与我们的服务器处于同一时区。因此,如果太平洋地区的客户端输入时间为 4:00 PM 的日期,则服务器(中部时间)会将其视为 6:00 PM,这是正确的,因为它们代表同一时间UTC,但我真正想要的是知道用户输入 4:00 PM,并注意弄清楚服务器端实际代表的 UTC 时间。
我在服务器上使用 NodaTime 来处理将用户输入时间转换为要存储在数据库中的实际 UTC 时间。
我在 javascript 中的当前解决方案是,当从服务器接收日期时,将它们 返回 转换为 UTC,以便我获得服务器传递的实际日期。这部分感觉很hacky。
function convertToUTCDate(date) {
var utcDate = new Date(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds()
);
return utcDate;
}
我查看了很多 Whosebug 问题,并且学习了 Matt Johnson 在 PluralSight 中的日期和时间基础课程。我在 javascript 和 .NET 中学到了很多关于日期的好原则,但它们似乎都与我的情况不同:我不在乎用户的时区是什么,我想要所有日期以学校时区显示,并将日期输入视为在学校时区上下文中输入时间。
是否有一种简单且非 hacky 的方法可以在两个方向上做我想做的事情? (客户端向服务器发送日期,服务器向客户端发送日期)
不是 100% 确定我明白你说的。
但是如果你使用像 momentjs 这样的东西,那么不要转换为服务器上的时区。到处使用UTC日期,然后告诉客户端javascript要使用的时区是什么,然后使用moment将utc时间转换成你想要显示的时区。
从您描述的情况来看,听起来最简单的事情就是只传递不合格的日期和时间值,而不是本地或 UTC。
在服务器上,使用 DateTime
值 Unspecified
类型,或使用 Noda Time 的 LocalDateTime
.
保留 JSON.Net 的默认日期格式处理,即 DateFormatHandling.IsoDateFormat
和 DateTimeZoneHandling.RoundtripKind
。你很少需要修改这些,只要你适当注意Kind
。
- 如果您直接序列化 Noda Time 类型,请确保使用
ConfigureForNodaTime
连接 NodaTime.Serialization.JsonNet 库,如 in the user guide. 所述
通过网络,数据应该类似于 "eventTime" : "2016-03-01T10:00:00"
。不要包含 Z
,因为您不发送 UTC。也不包括偏移量。
在客户端,不要使用 Date
对象。它总是在当地时区工作。相反,请考虑使用 moment.js.
目前没有 "unspecified" 模式,但您可以使用 UTC 模式伪造它,即使该值实际上不是 UTC 格式,这仍然适用于格式化。呼叫moment.utc(yourvalue)
。不要使用 moment(yourvalue)
,因为它将处于 local 模式,并且会像 Date
对象一样采用本地时区的 DST 行为.
或者,您真的可以只使用 RobG 在评论中建议的字符串。您只需要自己在用户输入和有线格式之间解析和格式化它们。有些人可能会觉得这很容易,而另一些人则更愿意让图书馆来做。
最后,请注意,我是根据您描述的场景中的许多假设提出此建议的。如果还有您没有解释的其他用例,它可能是理想的,也可能不是理想的。例如,如果您通过此 API 向某些第三方发送相同的值,那么使用包含偏移量的序列化 DateTimeOffset
可能更合适。
还认识到您可以在所有客户端执行此操作,使用诸如 moment-timezone 之类的东西。然而,对于这种特殊情况,这可能不是必需的。
在我们的 ASP.NET 私立学校 MVC 网络应用程序中,用户可以输入日历事件的日期(以及其他内容,即家庭作业截止日期),这些日期将使用 学校的 时区,不一定与他们自己的计算机相同(即,如果他们在另一个州度假时使用网络应用程序)。
我只想按字面意思传递日期,这样当我在服务器上接收到它们时,我可以确切地知道用户输入的值是什么,并让服务器根据学校的时区。
另一方面,我也希望服务器将已调整的日期传递给客户端,然后客户端应按原样显示这些日期。我不希望日期自动转换为计算机时区,因为我希望所有日期都显示为学校时区。
我们将 Json.NET 用于 serializing/deserializing JSON。我们当前的日期设置是:
serializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
也许我应该为 DateTimeZoneHandling 使用不同的选项...?
反序列化日期的最大问题是用户输入的实际日期不会被保留,除非它们与我们的服务器处于同一时区。因此,如果太平洋地区的客户端输入时间为 4:00 PM 的日期,则服务器(中部时间)会将其视为 6:00 PM,这是正确的,因为它们代表同一时间UTC,但我真正想要的是知道用户输入 4:00 PM,并注意弄清楚服务器端实际代表的 UTC 时间。
我在服务器上使用 NodaTime 来处理将用户输入时间转换为要存储在数据库中的实际 UTC 时间。
我在 javascript 中的当前解决方案是,当从服务器接收日期时,将它们 返回 转换为 UTC,以便我获得服务器传递的实际日期。这部分感觉很hacky。
function convertToUTCDate(date) {
var utcDate = new Date(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds()
);
return utcDate;
}
我查看了很多 Whosebug 问题,并且学习了 Matt Johnson 在 PluralSight 中的日期和时间基础课程。我在 javascript 和 .NET 中学到了很多关于日期的好原则,但它们似乎都与我的情况不同:我不在乎用户的时区是什么,我想要所有日期以学校时区显示,并将日期输入视为在学校时区上下文中输入时间。
是否有一种简单且非 hacky 的方法可以在两个方向上做我想做的事情? (客户端向服务器发送日期,服务器向客户端发送日期)
不是 100% 确定我明白你说的。
但是如果你使用像 momentjs 这样的东西,那么不要转换为服务器上的时区。到处使用UTC日期,然后告诉客户端javascript要使用的时区是什么,然后使用moment将utc时间转换成你想要显示的时区。
从您描述的情况来看,听起来最简单的事情就是只传递不合格的日期和时间值,而不是本地或 UTC。
在服务器上,使用
DateTime
值Unspecified
类型,或使用 Noda Time 的LocalDateTime
.保留 JSON.Net 的默认日期格式处理,即
DateFormatHandling.IsoDateFormat
和DateTimeZoneHandling.RoundtripKind
。你很少需要修改这些,只要你适当注意Kind
。- 如果您直接序列化 Noda Time 类型,请确保使用
ConfigureForNodaTime
连接 NodaTime.Serialization.JsonNet 库,如 in the user guide. 所述
- 如果您直接序列化 Noda Time 类型,请确保使用
通过网络,数据应该类似于
"eventTime" : "2016-03-01T10:00:00"
。不要包含Z
,因为您不发送 UTC。也不包括偏移量。在客户端,不要使用
Date
对象。它总是在当地时区工作。相反,请考虑使用 moment.js.目前没有 "unspecified" 模式,但您可以使用 UTC 模式伪造它,即使该值实际上不是 UTC 格式,这仍然适用于格式化。呼叫
moment.utc(yourvalue)
。不要使用moment(yourvalue)
,因为它将处于 local 模式,并且会像Date
对象一样采用本地时区的 DST 行为.或者,您真的可以只使用 RobG 在评论中建议的字符串。您只需要自己在用户输入和有线格式之间解析和格式化它们。有些人可能会觉得这很容易,而另一些人则更愿意让图书馆来做。
最后,请注意,我是根据您描述的场景中的许多假设提出此建议的。如果还有您没有解释的其他用例,它可能是理想的,也可能不是理想的。例如,如果您通过此 API 向某些第三方发送相同的值,那么使用包含偏移量的序列化 DateTimeOffset
可能更合适。
还认识到您可以在所有客户端执行此操作,使用诸如 moment-timezone 之类的东西。然而,对于这种特殊情况,这可能不是必需的。