.NET Noda Time 将本地日期时间转换为特定时区的 UTC

.NET Noda Time Converting Local DateTime To UTC for a specific Timezone

我正在使用 Noda Time 将 local datetime 转换为 UTC

这是我目前拥有的:

static string LocalTimeToUTC(string timeZone, string localDateTime)
{
    var pattern = LocalDateTimePattern.CreateWithInvariantCulture("dd/MM/yyyy HH:mm:ss");
    LocalDateTime ldt = pattern.Parse(localDateTime).Value;
    ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]);
    Instant instant = zdt.ToInstant();
    ZonedDateTime utc = instant.InUtc();
    string output = utc.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

    return output;
}

static void Main(string[] args)
{
    foreach (DateTime d in myDates)
    {
        DateTime utcTime = Convert.ToDateTime(LocalTimeToUTC("Europe/Amsterdam", d.ToString()));
        Console.WriteLine(utcTime);
    }

    Console.ReadKey();
}

问题出在夏令时:当时钟倒退 1 小时时。少了一个小时,看下面的结果。

   25/10/2014 19:00:00
   25/10/2014 20:00:00
   25/10/2014 21:00:00
   25/10/2014 22:00:00
   25/10/2014 23:00:00
   26/10/2014 01:00:00
   26/10/2014 02:00:00

如您所见,由于时钟更改,26/10/2014 00:00:00 丢失了。

我的问题是,有没有一种方法可以处理这个问题,这样就不会错过任何时间?填充缺失的时间?

您错过了一个小时,因为有两个 UTC 时刻都对应于相同的本地时间,因为时钟倒退。避免 "missing hours" 的唯一方法是在不明确的当地时间发出 两个 条目。

让我们看看 table 反过来,从 UTC 到本地时间,每个经过的小时有一个条目:

UTC                        Local time
2014-10-25 21:00:00Z       2014-10-25 23:00:00 +02
2014-10-25 22:00:00Z       2014-10-26 00:00:00 +02
2014-10-25 23:00:00Z       2014-10-26 01:00:00 +02
2014-10-26 00:00:00Z       2014-10-26 02:00:00 +02
2014-10-26 01:00:00Z       2014-10-26 02:00:00 +01 (clocks back!)
2014-10-26 02:00:00Z       2014-10-26 03:00:00 +01

所以左侧有 6 个不同的值,但右侧只有 5 个不同的值。

您可以使用 DateTimeZone.MapLocal(LocalDateTime) 得到一个 ZoneLocalMapping,其中将包含 0、1 或 2 个值,具体取决于本地 date/time 是否被跳过(由于向前跳转),明确的,或重复的(由于跳回)。 可能 给你你想要的,但你并不清楚你想要达到什么或你的输入数据代表什么。