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

时间:2014-04-01 17:58:18

标签: c# timezone

波多黎各和其他几个国家没有夏令时。我没有看到使用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);
    }

还有其他考虑方法吗?上述方法有什么不好吗?

2 个答案:

答案 0 :(得分:1)

TimeZoneInfo一起用于波多黎各的正确ID为"SA Western Standard Time"

DisplayName "(UTC-04:00) Georgetown, La Paz, Manaus, San Juan",不遵守夏令时。这很容易错过,但是"圣胡安"在显示名称中确实引用了San Juan, Puerto Rico

实际上很少有地方在Windows时区数据中没有明确的时区ID。有些确实存在,对于那些你必须创建一个固定的偏移区域。一个例子是Atikokan, Canada - 这是在东部时间,但不使用夏令时。

如果您担心该级别,则应该切换到IANA time zones,您可以使用Noda Time轻松完成此操作。

如果您对应选择哪个Windows时区存在疑问,可以随时将IANA时区与CLDR mappings进行比较。实际上,它表明"America/Puerto_Rico""SA Western Standard Time"的可能翻译之一。

答案 1 :(得分:0)

实际上有SupportsDaylightSavingTime属性指示时区是否使用DST。例如:

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
foreach(TimeZoneInfo zone in zones)
{
   if (! zone.SupportsDaylightSavingTime)
      Console.WriteLine(zone.DisplayName);
}

打印所有没有夏令时的时区。

如果波多黎各没有自己的时区,那么下一个最佳选择是找到匹配的时区(即相同的偏移量而没有DST)并使用它。如果不存在这样的区域,只需使用UTC并应用常量偏移。