TimeZoneInfo - .net核心1.1上的AdjustmentRule错误

时间:2017-04-05 21:29:56

标签: c# .net azure asp.net-core asp.net-core-mvc

我有一段代码可以让我获得当前的日期/时间(本地)。

它将在Azure上运行。

我正在获得普及时间并将其转换为英国当地时间(考虑到BST - 英国夏令时)。

从.NET 4.6.1 / Core项目迁移到.NET Core 1.1时,我现在遇到错误。

  

类型名称'AdjustmentRule'在类型中不存在   '的TimeZoneInfo'

     

'TimeZoneInfo'不包含'GetAdjustmentRules'的定义   没有扩展方法'GetAdjustmentRules'接受第一个   可以找到“TimeZoneInfo”类型的参数(你错过了吗?   使用指令或程序集引用?)

仅使用.NET Core 1.1 - 如何解决此问题?

public static DateTime GetLocalDateTimeNow()
{
    DateTime localDate = System.DateTime.Now.ToUniversalTime();

    // Get the venue time zone info
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
    TimeSpan timeDiffUtcClient = tz.BaseUtcOffset;
    localDate = System.DateTime.Now.ToUniversalTime().Add(timeDiffUtcClient);

    if (tz.SupportsDaylightSavingTime && tz.IsDaylightSavingTime(localDate))
    {
        TimeZoneInfo.AdjustmentRule[] rules = tz.GetAdjustmentRules();
        foreach (var adjustmentRule in rules)
        {
            if (adjustmentRule.DateStart <= localDate && adjustmentRule.DateEnd >= localDate)
            {
                localDate = localDate.Add(adjustmentRule.DaylightDelta);
            }
        }
    }

    DateTimeOffset utcDate = localDate.ToUniversalTime();

    return localDate;
}

我不介意更换实施,只要它考虑到BST并在.net核心1.1(没有4.6.1)上运行。

1 个答案:

答案 0 :(得分:3)

您不应该自己做任何事情 - 只需要TimeZoneInfo进行转换即可。这就是它的用途!

// Only need to do this once...
private static readonly TimeZoneInfo londonZone =
    TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

public static DateTime GetUkDateTimeNow() =>
    TimeZoneInfo.ConvertTime(DateTime.UtcNow, londonZone);

一些注意事项:

  • 我已将GetLocalDateTimeNow()重命名为GetUkDateTimeNow(),以明确说明它始终处理的是英国时区,而不是特定用户或计算机本地的时区
  • 在Unix上,您需要"Europe/London"而不是"GMT Standard Time"
  • 要使其独立于任何一个 - 实际上是系统本地时区数据 - 您可以使用我想要的Noda Time project来代替通常更清晰的代码。

几乎没有人需要在他们的代码中处理AdjustmentRule。我在Noda Time中做,因为我需要能够将TimeZoneInfo区域表示为Noda Time DateTimeZone对象,但这很不寻常。如果你需要使用它们,它们会比你想象的要复杂得多,并且.NET实现中出现了几次错误;我现在(就像今天一样)在Mono实现中反击错误......

顺便说一句,我强烈敦促你不要在任何地方使用DateTime.Now。始终使用DateTime.UtcNow,然后转换为系统本地时区,如果您确实需要。