在.net中获取亚利桑那州标准时间

Lui*_*iso 6 .net c# timezone

我有一个应用程序,通过使用系统名称将时区视为字符串,以便我们可以System.TimeZoneInfo通过执行以下操作来创建实际对象:

var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
Run Code Online (Sandbox Code Playgroud)

这些值会持久保存到DB,现在我们面临的问题是请求一个这样的对象Arizona Time不是标准时区.从我调查Arizona Time时间区域的变化,因为它没有观察到"日光节约".

我正在寻找一种在DB中设置一个值的方法,这样就不需要根据日光节省的变化来改变它.

有没有办法做到这一点?

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

Nik*_*pić 8

关于亚利桑那州时区

来自timeanddate.com:

有一种常见的误解,即亚利桑那州在夏季的太平洋夏令时(PDT)和冬季的山地标准时间(MST).由于MST和PDT具有相同的UTC偏移-7小时(UTC-7),因此亚利桑那州在夏季与当地加利福尼亚州和内华达州的当地时间相同.虽然时间相同,但亚利桑那州全年都使用标准时间(MST)."日光"时区(如MDT)主要用于每年切换到DST的区域

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

  • 美国/凤凰城(山地标准时间 - 亚利桑那州,纳瓦霍除外),没有观察到夏令时变化(DST),以及
  • America/Shiprock,观察夏令时.

亚利桑那州的.NET时区

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

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

TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time")
Run Code Online (Sandbox Code Playgroud)

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

TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time")
Run Code Online (Sandbox Code Playgroud)

所以,你会同时拥有IDS在数据库中,US Mountain Standard TimeMountain Standard Time,或者一些其他的字符串,你以后会映射到这些.NET时区的ID.

查看NodaTime,它可以帮助您处理日期,时间和时区.

最后,这是一个示例程序(使用NodaTime),演示了.NET US Mountain Standard Time(America/Phoenix,Arizona without DST)和Mountain Standard Time(America/Shiprock,Arizona with DST)之间的区别.

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)