处理没有夏令时的国家/地区的时区信息转换
本文关键字:地区 时区 信息 转换 国家 夏令时 处理 | 更新日期: 2023-09-27 17:56:04
波多黎各和其他几个国家没有夏令时。我没有看到使用 TimeZoneInfo 类指定给定国家/地区/区域设置是否支持夏令时的方法。
DateTime dt = DateTime.UtcNow;
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Atlantic Standard Time");
if (tz.IsDaylightSavingTime(dt))
Console.WriteLine("Daylight Savings");
关于我唯一能想到的是允许用户指定时区以及是否调整夏令时,然后使用TimeZoneInfo.GetUtcOffset而不是更直接的TimeZoneInfo.ConvertTimeFromUtc方法。
if (tz.IsDaylightSavingTime(dt) && !supportsDaylightSaving)
{
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero).AddHours(-1);
var dt3 = utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)).DateTime;
Console.WriteLine(dt3);
}
还有其他方法可以考虑吗?上述方法有什么不好吗?
波多黎各TimeZoneInfo
的正确 ID 是 "SA Western Standard Time"
。
它的DisplayName
为"(UTC-04:00) Georgetown, La Paz, Manaus, San Juan"
,并且不遵循夏令时。 这很容易错过,但显示名称中的"圣胡安"确实是指波多黎各的圣胡安。
实际上,很少有位置在 Windows 时区数据中没有不同的时区 ID。 有些确实存在,对于这些,您必须创建一个固定的偏移区域。 一个例子是加拿大的Atikokan - 它是东部时间,但不使用DST。
如果您担心这个级别,您可能应该切换到 IANA 时区,您可以使用 Noda Time 轻松完成。
如果您对应该选择哪个 Windows 时区有疑问,您可以随时将 IANA 时区与 CLDR 映射进行比较。 事实上,它表明"America/Puerto_Rico"
是"SA Western Standard Time"
的可能翻译之一。
实际上,有 SupportsDaylightSavingTime 属性指示时区是否使用 DST。例如:
ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
foreach(TimeZoneInfo zone in zones)
{
if (! zone.SupportsDaylightSavingTime)
Console.WriteLine(zone.DisplayName);
}
打印没有 DST 的所有时区。
如果波多黎各没有自己的时区,下一个最佳选择是找到匹配的时区(即相同的偏移量和没有 DST)并使用它。如果不存在此类区域,只需使用 UTC 并应用常量偏移量。