提问人:Ant 提问时间:10/10/2023 最后编辑:Matt Johnson-PintAnt 更新时间:10/11/2023 访问量:84
到 UTC 的本地不明确 DateTime
Local Ambiguous DateTime to UTC
问:
基本上,我如何将我知道是 GMT 的日期字符串转换为 UTC,其中日期不明确,因为它位于夏令时切换范围内。
例如,“29/10/2023 01:30:00” - 在格林威治标准时间中,时钟在 02:00 返回,这可能是第一次或第二次 - 在 C# 中,如果你在这个对象上,它将始终返回 01:30。.ToUniversalTime()
DateTime
有没有办法告诉它到 UTC 转换“嘿,这是 BST 时间”,下次告诉它这是非 BST 时间?
据我所知,我可以找到该对象,但它不允许我在使用它转换为 UTC 时指定非夏令时模式。TimeZoneInfo
对于上下文,这是针对调度应用程序的,例如每 15 分钟发生一次事件,数据来自外部 API,它以字符串形式为我提供日期时间,时区位于单独的属性中,例如“GMT BST”和“GMT”。
答:
1赞
Matt Johnson-Pint
10/11/2023
#1
通过您使用“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)");
评论
GetAmbiguousTimeOffsets