处理没有夏令时的国家/地区的时区信息转换

本文关键字:地区 时区 信息 转换 国家 夏令时 处理 | 更新日期: 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 并应用常量偏移量。