当服务器设置为UTC时,会识别DateTime

我的应用程序托管在Windows Azure上,其中所有服务器都设置为UTC。

我需要知道任何给定的DateTime何时需要夏令时。 为了简单起见,我们可以假设我的用户都在英国(所以使用格林威治标准时间)。

我用来转换我的DateTime对象的代码是

public static DateTime UtcToUserTimeZone(DateTime dateTime)
{
    dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);

    var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");

    var userDateTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);

    return DateTime.SpecifyKind(userDateTime, DateTimeKind.Local);
}

但是,以下测试在最后一行失败; 转换后的DateTime不知道它应该处于夏令时。

[Test]
public void UtcToUserTimeZoneShouldWork()
{
    var utcDateTime = new DateTime(2014, 6, 1, 12, 0, 0, DateTimeKind.Utc);
    Assert.IsFalse(utcDateTime.IsDaylightSavingTime());

    var dateTime = Utils.UtcToUserTimeZone(utcDateTime);
    Assert.IsTrue(dateTime.IsDaylightSavingTime());
}

请注意,只有当我的Windows时区设置为(UTC)协调世界时 ,这只会失败。 当它被设置为(UTC)都柏林,爱丁堡,里斯本,伦敦 (或任何其他观测夏令时的北半球时区)时,测试通过。 如果在Windows中更改此设置,则需要重新启动Visual Studio才能使更改完全生效。

我错过了什么?


  • 您缺少的主要内容是“格林威治标准时间”不是伦敦的TimeZoneInfo ID。 那实际上属于“(UTC)蒙罗维亚,雷克雅未克”。

    你想要“GMT标准时间”,它映射到“(UTC)都柏林,爱丁堡,里斯本,伦敦”

    是的,Windows时区很奇怪。 (至少你不住在法国,这被奇怪地标为“浪漫标准时间”!)

  • 另外,你不应该这样做:

    return DateTime.SpecifyKind(userDateTime, DateTimeKind.Local);
    

    这将使其他各种代码认为它来自本地机器的时区。 留下“未指定”种类。 (或者甚至更好,使用DateTimeOffset而不是DateTime

  • 然后,您还需要在TimeZoneInfo对象上使用.IsDaylightSavingsTime方法,而不是使用.DateTime对象上的.DateTime 。 (有两种不同的方法,具有相同的名称,不同的对象,具有不同的行为,哎哟!)

  • 但我完全同意,这太复杂和容易出错。 只需使用野田时间。 你会很高兴你做到了!


    您的最后一行指定该值位于正在运行的系统的本地时区中 - 但它不是真的......它使用不同的时区进行转换。

    在我看来,基本上DateTime有些破碎 - 这使得它很难正确使用。 没有办法说“此DateTime值在时区x中” - 您可以执行转换以查找特定的本地时间,但不记得时区。

    例如,从DateTime.IsDaylightSavingTime文档(强调我的):

    此方法确定当前DateTime值是否落在由TimeZoneInfo.Local属性返回的本地时区的夏令时范围内。

    显然我有偏见,但我建议使用我的Noda Time项目来代替 - 很可能使用ZonedDateTime 。 您可以调用GetZoneInterval获取该ZoneIntervalZonedDateTime ,然后使用ZoneInterval.Savings检查当前偏移是否包含夏令时组件:

    bool daylight = zonedDateTime.GetZoneInterval().Savings != Offset.Zero;
    

    这稍微啰嗦......我已经添加了一个功能请求,考虑添加IsDaylightSavingTime()方法来ZonedDateTime以及...

    链接地址: http://www.djcxy.com/p/29379.html

    上一篇: aware DateTime when server set to UTC

    下一篇: .NET/JavaScript ignores daylight saving (DST) when parsing ISO8601