【问题标题】:Getting the Arizona Standard Time in .net在 .net 中获取亚利桑那标准时间
【发布时间】:2017-07-14 11:17:16
【问题描述】:

我有一个应用程序,其中时区被视为字符串,通过使用系统名称,我们可以通过以下方式创建一个实际的 System.TimeZoneInfo 对象:

var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone);

这些值被持久化到数据库中,现在我们面临一个问题,即要求一个这样的对象位于不是标准时区的Arizona Time 上。根据我的调查,Arizona Time 更改了时区,因为它没有遵守“夏令时”。

我正在寻找一种在 DB 中设置一个值的方法,这样就无需根据夏令时的变化进行更改。

有没有办法做到这一点?

即使我必须更改一点代码来获取TimeZoneInfo 对象。对我来说真正重要的是确定Arizona Time对应的实际时区的方法

【问题讨论】:

    标签: c# .net timezone


    【解决方案1】:

    关于亚利桑那时区

    来自timeanddate.com

    人们普遍认为亚利桑那州处于太平洋日光下 夏季时间 (PDT) 和山地标准时间 (MST) 在冬季。因为 MST 和 PDT 具有相同的 UTC 偏移量 负 7 小时 (UTC-7),亚利桑那州的当地时间与邻近地区相同 夏季在加利福尼亚州和内华达州。 虽然 时间相同,亚利桑那州全年使用标准时间 (MST)。 “日光”时区,例如 MDT,主要用于 每年切换到夏令时

    IANA(tz 数据库)时区数据库包含亚利桑那州的两个时区:

    • 美国/凤凰城(山地标准时间 - 亚利桑那州,纳瓦霍除外),观察夏令时变化 (DST),并且
    • America/Shiprock,遵守 DST。

    .NET 中的亚利桑那时区

    根据用户在亚利桑那州的确切位置,您应该使用 America/PhoenixAmerica/Shiprock 时区,因此您需要数据库中的两个值.但是,如果您尝试使用 tz 数据库名称获取 TimeZoneInfo.FindSystemTimeZoneById 的时区,您将获得 System.TimeZoneNotFoundException

    为了获得不遵守 DST 的亚利桑那时区(美国/凤凰城),您可以使用:

    TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time")
    

    为了获得遵守 DST 的亚利桑那时区(America/Shiprock),您可以使用:

    TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time")
    

    因此,您的数据库中将有两个 ID,US Mountain Standard TimeMountain Standard Time,或者您稍后将映射到这些 .NET 时区 ID 的其他字符串。

    查看NodaTime,它可以在处理日期、时间和时区方面为您提供很多帮助。

    最后,这是一个示例程序(带有 NodaTime),它演示了 .NET 美国山地标准时间美国/凤凰城,亚利桑那州没有 DST)和山地标准时间美国/Shiprock,亚利桑那州,夏令时)。

    using System;
    
    using NodaTime;
    using NodaTime.TimeZones;
    
    namespace TimeZoneExample
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Arizona without daylight saving time (TZ: America/Phoenix)
                var mstWithoutDstTz = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");
    
                // Arizona with daylight saving time (TZ: America/Shiprock)
                var mstWithDstTz = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
    
                // NodaTime BclDateTimeZone for Arizona without daylight saving time
                var mstWithoutDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithoutDstTz);
    
                // NodaTime BclDateTimeZone for Arizona with daylight saving time
                var mstWithDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithDstTz);
    
                // January 1, 2017, 15:00, local winter date
                var localWinterDate = new LocalDateTime(2017, 01, 01, 15, 00);
    
                // NodaTime ZonedDateTime for Arizona without daylight saving time: January 1, 2017, 15:00
                var winterTimeWithoutDst = mstWithoutDstNodaTz.AtStrictly(localWinterDate);
    
                // NodaTime ZonedDateTime for Arizona with daylight saving time: January 1, 2017, 15:00
                var winterTimeWithDst = mstWithDstNodaTz.AtStrictly(localWinterDate);
    
                // Both time zones have the same time during winter
                Console.WriteLine($"Winter w/o DST: {winterTimeWithoutDst}"); // 2017-01-01T15:00:00 US Mountain Standard Time (-07)
                Console.WriteLine($"Winter w/ DST: {winterTimeWithDst}"); // 2017-01-01T15:00:00 Mountain Standard Time (-07)
    
                // add 180 days to get June 30, 2017
                var sixMonthsToSummer = Duration.FromTimeSpan(new TimeSpan(180, 0, 0, 0));
    
                // During summer, e.g. on June 30, Arizona without daylight saving time is 1 hour behind.
                Console.WriteLine($"Summer w/o DST: {winterTimeWithoutDst + sixMonthsToSummer}"); // 2017-06-30T15:00:00 US Mountain Standard Time (-07)
                Console.WriteLine($"Summer w/ DST: {winterTimeWithDst + sixMonthsToSummer}"); // 2017-06-30T16:00:00 Mountain Standard Time (-06)
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果我正确理解您的问题,您想创建一个代表“亚利桑那时间”的自定义时区,该时区与 UTC 有一个恒定的偏移量,而与一年中的日期无关。

      如果是这样,你应该可以使用静态方法

      TimeZoneInfo.CreateCustomTimeZone
      

      只需将 TimeSpan 设置为您需要的 UTC 小时数(据我所知为 -7 小时)。

      https://msdn.microsoft.com/en-us/library/bb309898(v=vs.110).aspx

      编辑:您也可以通过简单地使用命名时区来取得一些成功

      "US Mountain Standard Time" 
      

      应该代表相同。

      【讨论】:

        猜你喜欢
        • 2014-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-25
        • 2016-07-03
        • 1970-01-01
        • 2019-08-22
        • 1970-01-01
        相关资源
        最近更新 更多