2

我有一个输入:

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

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

.net 或 nodatime 中进行该转换的最佳方式是什么。我基本上是在 C# 中寻找这种方法的等价物:

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

但是上面的这个 .Net 方法只适用于 Windows 时区名称(而且我有 Olson 名称)

4

2 回答 2

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将其应用于目标区域。

于 2013-03-04T23:59:33.693 回答
3

马特(非常好)答案第二部分的替代方案:

// 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;
于 2013-03-05T04:35:40.180 回答