我有一个输入:
我需要将时间转换为另一个奥尔森时区(America / Los_Angeles)
.net或nodatime进行转换的最佳方法是什么。我基本上在C#中寻找相当于这个方法的东西:
var timeInDestinationTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(CurrentSlot.Date, TimeZoneInfo.Local.Id,
room.Location.TimeZone.TimeZoneName);
但上面的.Net方法仅适用于Windows时区名称(我有Olson名称)
答案 0 :(得分:4)
观察:
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
将其应用于目标区域。
答案 1 :(得分:3)
替代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;