不考虑夏令时的 UTC 日期

Date to UTC not taking into account daylight savings

我正在使用带时区(东部标准时间)的日期 (1/1/2018 11:30 AM) 并将其转换为 UTC 日期 (2018-01-01T16:30:00Z)。原始日期实际上是东部夏令时,因此当开发人员使用 UTC 进行转换时,他们得到的是 12:30 下午而不是 11:30 上午。如果我在 8/26/2018 11:30 AM 做,它工作正常。我的时区采用 .NET Windows 格式。

有没有办法通过我的以下方法获得正确的 UTC,该 UTC 具有来自 NodaTime 标准时区的夏令时?

2018-01-01T16:30:00Z = Helper.GetUtcTimeZone("1/1/2018 11:30 AM", "Eastern Standard Time").ToString();

方法

public static Instant GetUtcTimeZone(DateTime dateTime, string timeZone)
{
    var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone ?? TimeZoneInfo.Local.StandardName);

    if (timeZoneInfo != null)
    {
        if (dateTime.Kind == DateTimeKind.Unspecified)
        {
            dateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZoneInfo);
        }
    }

    return Instant.FromDateTimeUtc(dateTime);
}

如果想继续使用TimeZoneInfo,直接使用即可。不需要您添加的所有额外逻辑。

public static Instant GetUtcTimeZone(DateTime dateTime, string timeZone)
{
    TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
    DateTime utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZoneInfo);
    return Instant.FromDateTimeUtc(utcDateTime);
}

虽然真的,一旦您使用了 NodaTime,就没有理由这样做了。只需使用其内置功能:

public static Instant GetUtcTimeZone(DateTime dateTime, string timeZone)
{
    LocalDateTime ldt = LocalDateTime.FromDateTime(dateTime);
    DateTimeZone tz = DateTimeZoneProviders.Bcl[timeZone];
    return ldt.InZoneLeniently(tz).ToInstant();
}

一个重要的注意事项:您可以退回到 TimeZoneInfo.Local.StandardName。这是不安全的——因为 StandardName 字段是 本地化的 ,而且并不总是匹配标识符的名称,即使是英文。如果您需要标识符,请使用 Id 而不是 StandardName。在NodaTime中,您可以使用DateTimeZoneProviders.Bcl.GetSystemDefault().