我有一个输入:
- 时间(上午8:00(
- 奥尔森时区(美国/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;