日期时间+时区->NodaTime转换

4

当我查找将时间转换为NodaTime的方法时,我发现了许多帖子,但没有一个给出我需要的简单明了的答案。

我的需求是:

- A DateTime object (DateTime myDateTime)
- An Olson timezone (var TZ = "America/Los_Angeles")

我希望:

- A ZonedDateTime object (ZonedDateTime myZonedDateTime)

理想情况下,我正在寻找一些类似于助手的东西,例如:
var myZonedDateTime = ZonedDateTime.From(myDateTime, TZ);

我看到的所有示例都将日期转换为字符串,然后解析字符串,这似乎非常奇怪。

有一个ZonedDateTime.FromDateTimeOffset()方法,但偏移量和时区是不同的,因为时区可以处理夏令时。


DateTime 的“种类”是什么?如果 DateTime 值有歧义或被跳过,您想发生什么?(我希望这只涉及使用 LocalDateTime.FromDateTime(myDateTime).InZoneLeniently(zone) 或类似方法实现。) - Jon Skeet
这些是飞机航班时间,它们以当地时间和Olson时区表示;时间以本地时间显示,但在内部我们需要将其转换为UTC(考虑夏令时)进行一些计算。 - Thomas
我还没有考虑过不明确与跳过部分,因为这是我面临的一个非常新的问题,我正在努力解决它 :) - Thomas
这就是它们在逻辑上的含义 - 但 myDateTime.Kind 返回什么呢?首先,myDateTime 是从哪里来的?(如果是字符串,最好直接解析为 LocalDateTime。)我假设你已经发现了 DateTimeZoneProviders.Tzdb [id] 来获取 DateTimeZone - Jon Skeet
日期以Olson TZ字符串形式提供;是的,我已经成功获取了时区。 - Thomas
好的,如果它们作为字符串出现,您可以使用ZonedDateTimePattern一次完成整个操作。我根据问题中的信息添加了一个答案,但是如果您想使用字符串版本更新它,我可以写一个额外的部分。 - Jon Skeet
1个回答

11

听起来你只是想要:

var local = LocalDateTime.FromDateTime(myDateTime);
var zone = DateTimeZoneProviders.Tzdb[id];
var zoned = local.InZoneLeniently(zone);

除此之外:

  • 您很可能希望编写自己的规则,而不是使用 InZoneLeniently
  • 如果您不确定时区ID是否会被Noda Time识别,可以使用DateTimeZoneProviders.Tzdb.GetZoneOrNull(id)

由于我们的时区列表相当固定(它是机场),我将通过 NodaTime 运行整个列表,以确保没有遗漏;非常感谢 Jon,这真的很有帮助! - Thomas
1
@Thomas - 你可能会发现我在这里提供的代码(https://gist.github.com/mj1856/6d219c48697c550c2476)有用,它为世界上所有机场提供了TZDB和Windows时区。 - Matt Johnson-Pint

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