如何将时间和奥尔森时区转换为另一个奥尔森时区的时间

本文关键字:时区 时间 奥尔森 另一个 转换 | 更新日期: 2023-09-27 18:01:55

我有一个输入:

  1. 时间(上午8:00(
  2. 奥尔森时区(美国/New_York(

我需要将时间转换为另一个奥尔森时区(美国/Los_Angeles(

在.net或nodatime中进行转换的最佳方法是什么。 我基本上是在 C# 中寻找此方法的等效项:

  var timeInDestinationTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(CurrentSlot.Date, TimeZoneInfo.Local.Id,
                                                                            room.Location.TimeZone.TimeZoneName);

但是上面的这个.Net方法仅适用于Windows时区名称(我有奥尔森的名字(

如何将时间和奥尔森时区转换为另一个奥尔森时区的时间

观察:

var tzdb = DateTimeZoneProviders.Tzdb;
var zone1 = tzdb["America/New_York"];
var ldt1 = new LocalDateTime(2013, 3, 4, 8, 0); // March 4th, 2013 - 8:00 AM
var zdt1 = zone1.AtLeniently(ldt1);
var zone2 = tzdb["America/Los_Angeles"];
var zdt2 = zdt1.ToInstant().InZone(zone2);
var ldt2 = zdt2.LocalDateTime;

注意对AtLeniently的呼唤 - 那是因为你没有足够的信息来绝对确定你正在谈论的时刻。 例如,如果您谈论的是 DST 回退转换当天的凌晨 1:30,您将不知道您是在转换之前还是之后谈论。 AtLeniently会做出你的意思。 如果您不希望出现这种行为,则必须提供偏移量,以便知道您正在谈论的本地时间。

实际的转换是通过ToInstant完成的,它正在获取您正在谈论的UTC时刻,然后InZone将其应用于目标区域。

Matt(非常好(答案的第二部分的替代方案:

// All of this part as before...
var tzdb = DateTimeZoneProviders.Tzdb;    
var zone1 = tzdb["America/New_York"];
var ldt1 = new LocalDateTime(2013, 3, 4, 8, 0); // March 4th, 2013 - 8:00 AM
var zdt1 = zone1.AtLeniently(ldt1);
var zone2 = tzdb["America/Los_Angeles"];
// This is just slightly simpler - using WithZone, which automatically retains
// the calendar of the existing ZonedDateTime, and avoids having to convert
// to Instant manually
var zdt2 = zdt1.WithZone(zone2);
var ldt2 = zdt2.LocalDateTime;