基本上,如何将我知道的 GMT 日期字符串转换为 UTC,其中日期不明确,因为它位于夏令时切换范围内。
例如“29/10/2023 01:30:00” - 在 GMT 中,时钟在 02:00 倒退,这可能是第一次或第二次 - 在 C# 中,如果您
.ToUniversalTime()
在此 DateTime
对象上,它总是返回 01:30。
有没有办法告诉它到 UTC 转换“嘿这是 BST 时间”,然后下次告诉它这是非 BST 时间?
据我所知,我可以找到
TimeZoneInfo
对象,但它不允许我在使用它转换为 UTC 时指定非夏令时模式。
对于上下文,这是一个调度应用程序,例如每 15 分钟发生一次事件,数据来自外部 API,该 API 为我提供字符串形式的日期时间,以及单独属性中的时区,例如“GMT BST”和“GMT” '.
通过您使用“GMT”和“BST”,我假设您给出的是英国时间的示例,其中使用 GMT (UTC+0) 作为标准时间,使用 BST (UTC+1) 作为夏令时。假设您可以根据输入值判断您处于哪个阶段,那么在转换为 UTC 时您确实可以使用该信息。
这是适用于任何时区的扩展方法:
public static DateTime ToUniversalTime(this DateTime dt, TimeZoneInfo tz, bool isDst)
{
// If we're not dealing with unspecified kind, then the normal ToUniversalTime method is used.
// Thus, the tz and isDst parameters are ignored.
if (dt.Kind != DateTimeKind.Unspecified)
{
return dt.ToUniversalTime();
}
// Handle invalid values (impossible values in the local time zone, due to advancing local time).
if (tz.IsInvalidTime(dt))
{
throw new ArgumentException("Invalid local date and time for the specified time zone.");
}
// For ambiguous values, choose the offset for the indicated time zone and isDst flag.
if (tz.IsAmbiguousTime(dt))
{
TimeSpan[] offsets = tz.GetAmbiguousTimeOffsets(dt);
Array.Sort(offsets);
TimeSpan offset = isDst ? offsets[1] : offsets[0];
DateTimeOffset dto = new DateTimeOffset(dt, offset);
return dto.UtcDateTime;
}
// Simple case
return TimeZoneInfo.ConvertTimeToUtc(dt, tz);
}
并将其与您的示例一起使用:
// For the UK, use "Europe/London" (or "GMT Standard Time" on Windows before .NET 6)
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Europe/London");
DateTime london = new DateTime(2023, 10, 29, 1, 30, 0);
DateTime utcFromDst = london.ToUniversalTime(tz, true);
DateTime utcFromStd = london.ToUniversalTime(tz, false);
Console.WriteLine($"London: {london}");
Console.WriteLine();
Console.WriteLine($"UTC: {utcFromDst} (assuming input was daylight time)");
Console.WriteLine($"UTC: {utcFromStd} (assuming input was standard time)");