不考虑夏令时的 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()
.
我正在使用带时区(东部标准时间)的日期 (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()
.