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

var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone);

这些值一直保存到数据库中,现在我们面临一个问题,即要求将这样的对象放在不是标准时区的Arizona Time上。根据我的调查,由于Arizona Time不遵守“夏令时”,因此更改了时区。

我正在寻找一种在DB中设置一个值的方法,这样就无需根据日光节约量的变化来更改它。

有没有办法做到这一点?

即使我必须更改一点代码才能获得TimeZoneInfo对象。对我而言真正重要的是一种确定与Arizona Time对应的实际时区的方法

最佳答案

关于亚利桑那时区

timeanddate.com:



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

  • America/Phoenix(山地标准时间-亚利桑那州,纳瓦霍除外),它执行而不是来观察夏时制(DST)和
  • America/Shiprock,它遵守DST。

  • .NET中的亚利桑那州时区

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

    为了获得不遵守DST(美国/凤凰城)的亚利桑那州时区,您可以使用:
    TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time")
    

    为了获得确实遵守DST(美国/夏普洛克)的亚利桑那州时区,您可以使用:
    TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time")
    

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

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

    最后,这是一个示例程序(带有NodaTime),演示了.NET美国山区标准时间(美国/凤凰城,亚利桑那州,没有DST)和山区标准时间(美国/Shiprock,亚利桑那州,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)
            }
        }
    }
    

    关于c# - 在.net中获取亚利桑那州标准时间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42424829/

    10-10 22:20