zoukankan      html  css  js  c++  java
  • C#关于TimeZone和TimeZoneInfo类的比较

    在工作中我们遇到国际化时,经常要处理时区问题。这两个类都是处理时区的我们应该怎样选择呢?

    TimeZone 类来检索有关当前时区的信息,并将时间从本地时间转换为协调世界时 (UTC),也就是说这个类是用来处理LocalTimeZone和UTC时间的。

    TimeZoneInfo类可以处理系统上预定义的任何时区、创建新时区,以及轻松地将日期和时间从一个时区转换到另一个时区。从微软的官方提示上我们可以看出,TimeZone 类基本已经被TimeZoneInfo类取代了。

    首先介绍下TimeZone类吧,TimeZone的CurrentTimeZone属性和TimeZoneInfo的Local一属性类似,得到的都是LocalTimeZone。

    TimeZone的GetDaylightChanges方法是得到时区某一年的夏令时时间。这里提到的夏令时时间中国是不支持的,像美国和加拿大的一些国家是支持的。如果TimeZone是太平洋时区(Pacific Time Zone),这个时区的标准时间是UTC-8,夏令时时间的UTC-7。调用GetDaylightChanges返回的结果是2012-3-11 2:00 to 2012-11-4 2:00,这就是太平洋时区在这一年的夏令时开始和结束时间。

      DaylightTime daylight = localZone.GetDaylightChanges(currentYear);
                // Display the daylight saving time range for the current year.
                Console.WriteLine(
                    "Daylight saving time for year {0}:", currentYear);
                Console.WriteLine("{0:yyyy-MM-dd HH:mm} to " +
                    "{1:yyyy-MM-dd HH:mm}, differ: {2}",
                    daylight.Start, daylight.End, daylight.Delta);

    TimeZone的GetUtcOffset方法得到的是Local和UTC时间的偏移量,和TimeZoneInfo的BaseUtcOffset方法类似。太平洋时区的返回结果是-7:00:00,这是因为现在是8月份太平洋时区执行的是夏令时时间,所以和UTC时间是相差7个小时。

    //Pacific Standard TimeZone
    TimeSpan currentOffset = localZone.GetUtcOffset(currentDate);
    Console.WriteLine("UTC offset:{0}", currentOffset);

    再说下TimeZoneInfo这个类,它的Utc和Local属性直接得到的是UTC TimeZone和Local TImeZone对象,用起来很方便。

    TimeZoneInfo的ConvertTime(DateTime, TimeZoneInfo)方法,把一个时间转到一个时区你可能会感觉很纳闷。虽然Datetime没有时区属性但也是有时区的,因为DateTime在创建时候可以指定DateTimeKind可以是Local或Utc,没指定的话就是Unspecified默认按Local来处理的。

    TimeZoneInfo的CreateCustomTimeZone方法可以创建带有夏令时规则的时区。对于FloatingRule是指夏令时发生某月第几个星期所以是浮动的,而FixedRule是指某月的多少号是固定的。

                // Define transition times to/from DST
                TimeZoneInfo.TransitionTime startTransition, endTransition;
                startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0),
                                                                                  10, 2, DayOfWeek.Sunday);
                endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0),
                                                                                3, 2, DayOfWeek.Sunday);
                // Define adjustment rule
                TimeSpan delta = new TimeSpan(1, 0, 0);
                TimeZoneInfo.AdjustmentRule adjustment;
                adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
                // Create array for adjustment rules
                TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
                // Define other custom time zone arguments 
                string displayName = "(GMT-04:00) Antarctica/Palmer Time";
                string standardName = "Palmer Time";
                string daylightName = "Palmer Daylight Time";
                TimeSpan offset = new TimeSpan(-4, 0, 0);
                TimeZoneInfo palmer = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, displayName, standardName, daylightName, adjustments);
                Console.WriteLine("\nThe current time is {0} {1}",
                                  TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local, palmer),
                                  palmer.StandardName);

    TimeZoneInfo的IsAmbiguousTime(DateTime) 方法,说这我主要想说下AmbiguousTime。通过下面的代码你会发现,在夏令时往标准时间转的时候,1点到2点之间的时间都是AmbiguousTime。因为这段时间对应着Utc-8和Utc-7两个时区,所以是时间是不能确定的。

              DateTime baseTime = new DateTime(2007, 11, 4, 0, 59, 00, DateTimeKind.Unspecified);
                DateTime newTime;
    
                // Get Pacific Standard Time zone
                TimeZoneInfo pstZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    
                // List possible ambiguous times for 63-minute interval, from 12:59 AM to 2:01 AM 
                for (int ctr = 0; ctr < 63; ctr++)
                {
                    // Because of assignment, newTime.Kind is also DateTimeKind.Unspecified
                    newTime = baseTime.AddMinutes(ctr);
                    Console.WriteLine("{0} is ambiguous: {1} ;{2} is daylighttime: {3} ", newTime, pstZone.IsAmbiguousTime(newTime), newTime, pstZone.IsDaylightSavingTime(newTime));
                }

    当然TimeZoneInfo对象还可以序列化成Xml,也可以反序列化。TimeZoneInfo对象还可以被存在资源文件里面,用的时候再取出来。

    关于DateTimeOffset的理解,我认为它就是DateTime加上一个UtcOffset的偏移量。

    这是我写的第一篇文章,虽然写的一般却是我自己一个字一个字敲出来的,希望能对大家时区的理解有帮助。

  • 相关阅读:
    3.27 课堂 笔记
    第四周 4-2
    3-26
    Java EE期末项目
    条件查询、SQL、JPQL、HQL比较
    J2EE 第八周(04.23-04.29)
    J2EE 第七周(04.16-04.22)
    J2EE 第六周(04.09-04.15)
    J2EE 第五周(04.02-04.08)
    J2EE 第四周(03.26-04.01)
  • 原文地址:https://www.cnblogs.com/dongjh/p/2664676.html
Copyright © 2011-2022 走看看