使用Nodatime将特定时区的DateTime转换为UTC?

6

好的,我有一个托管在中央标准时间区的 Web 服务器。IIS 服务器已配置为此时区,因此每当在服务器上使用 DateTime.Now 或创建新的 DateTime(kind 属性为 Local)时,它的时间都是中央时间。

问题在于该网站是一个国际应用程序,我可能有来自美国或加拿大任何地方的客户。网站的一个功能是“调度器”,用于安排预约。为了简化开发,我们决定将数据库中所有 DateTime 值以 UTC 格式存储,并且 API 的所有流量也都是 UTC。但问题在于,我经常在服务器端创建日期/时间值时遇到问题。

例如,假设我需要在服务器上为太平洋标准时间区的客户编程创建一个早上 8 点的预约。过去,我曾经做过这样的事情:

var appointment = new new DateTime(2015, 04, 17, 08, 00, 00, DateTimeKind.Unspecified)
var utcAppointment = TimeZoneInfo.ConvertTimeToUtc(appointment,
                        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"))

我在程序中进行许多其他日期/时间操作,现在正在考虑直接转用Nodatime。我知道可以相对容易地从Nodatime变量中获取UTC DateTime。我困惑的是如何为特定时区的特定日期/时间创建一个Nodatime变量?所有我看到的例子都与模式有关,并涉及字符串读取或创建一个实例(基本上是“现在”)。我想做的是将现有的BCL DateTime对象(无论“类型”如何)转换为具有我设置的特定时区的Nodatime对象。我认为Nodatime是一个很棒的库,但只阅读用户指南就让我感到困惑,无法将其转换为BCL。

我之前在这里问过类似的问题(https://dev59.com/umsz5IYBdhLWcg3w8Mmr),但那不是一个关于NodaTime的问题。那里的讨论可能对未来阅读此问题的人有所帮助。此外,我可以赞同Jon Skeet的建议,在Web API中适当使用NodaTime类型,例如,使用LocalTime来表示您的时间表中的时间部分 - 甚至有一个辅助库用于序列化,即NodaTime.Serialization.JsonNet。 - Stephen Kennedy
1个回答

11

我困惑的是如何在特定日期/时间为特定时区创建一个Nodatime变量?

这相对容易:

LocalDateTime local = new LocalDateTime(2015, 4, 17, 8, 0, 0);
DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];
ZonedDateTime zonedTime = local.InZoneLeniently(zone);

"宽松"部分实际上取决于您希望在8:00被跳过或不明确时发生什么-这种情况不会发生,但这是需要记住的事情。 Noda Time可以以各种方式解决这个问题-用户指南详细介绍了这一点。

请注意,如果您更喜欢考虑时区进行转换,则可以使用zone.AtLeniently(local) - 它们是完全等效的。


如果我拥有一个现有的BCL DateTime对象,我可以使用LocalDateTime.FromDateTime(objectName)吗? - SpaceCowboy74
@SpaceCowboy74:是的,虽然我建议尽可能广泛地使用Noda Time类型。 - Jon Skeet
明白了。问题在于有时外部力量和WebApi本身会向我传递DateTime对象。我需要消耗它们以转换为UTC。我进行了一些沙盒测试,并能够使用您上面的代码来完成,然后通过调用ToDateTimeUtc将zonedTime传递给EntityFramwork。 - SpaceCowboy74
@SpaceCowboy74:没错 - 你应该能够配置一个Web API,以提供Noda Time值,而不是使用DateTime,但如果你想转换的话也可以。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接