时间和时区

时区的概念
        地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总比西边的早。东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们的日常生活和工作都带来许多不便。
        为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议上,规定将全球划分为24个时区。它们是中时区(零时区)、东1-12区,西1-12区。每个时区横跨经度15度,时间正好是1小时。最后的东、西第12区各跨经度7.5度,以东、西经180度为界。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时。相邻两个时区的时间相差1小时。例如,我国东8区的时间总比泰国东7区的时间早1小时,而比日本东9区的时间晚1小时。因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致。凡向西走,每过一个时区,就要把表拨慢1小时;凡向东走,每过一个时区,就要把表拨快1小时。
        实际上,世界上不少国家和地区都不严格按时区来计算时间。为了在全国范围内采用统一的时间,一般都把某一个时区的时间作为全国统一采用的时间。例如,我国把首都北京所在的东8区的时间作为全国统一的时间,称为北京时间。又例如,英国、法国、荷兰和比利时等国,虽地处中时区,但为了和欧洲大多数国家时间相一致,则采用东1区的时间。

net中的相关类

        除了基本的 DateTime 结构外,.NET Framework 还提供了下列类来支持对时区的处理:
        TimeZone
        使用此类可以处理系统的本地时区和协调世界时 (UTC) 区域。 TimeZone 类的大部分功能已由 TimeZoneInfo 类取代。
        TimeZoneInfo
        使用此类可以处理系统上预定义的任何时区、创建新时区,以及轻松地将日期和时间从一个时区转换到另一个时区。
        DateTimeOffset
        使用此结构可以处理 UTC 偏移量(即差值)已知的日期和时间。DateTimeOffset 结构将日期和时间值与该时间的 UTC 偏移量组合在一起。由于它与 UTC 存在这种关系,因此单个日期和时间值可以明确地标识单个时间点。这就使得 DateTimeOffset 值比 DateTime 值在不同计算机之间具有更好的可移植性。

在 DateTime、DateTimeOffset 和 TimeZoneInfo 之间进行选择

        使用日期和时间信息的 .NET Framework 应用程序存在相当大的差异,它们可以通过多种方式使用该信息。日期和时间信息较常见的用法包括以下一种或多种:
  •     仅反映日期,时间信息并不重要。
  •     仅反映时间,日期信息并不重要。
  •     反映不依赖于特定时间和地点的抽象日期和时间(例如,大部分国际连锁店都在每个工作日的上午 9:00 开始营业)。
  •     从 .NET Framework 之外的源中检索日期和时间信息,这种源中的日期和时间信息通常以简单的数据类型进行存储。
  •     唯一、明确地标识单个时间点。有些应用程序只要求主机系统上的日期和时间明确,而其他一些应用程序则要求跨系统的日期和时间都必须明确(也就是说,在一个系统上序列化的日期可以进行有意义的反序列化,并用在世界上其他任何地方的系统上)。
  •     保留多个相关时间(如请求者的本地时间和服务器接收 Web 请求的时间)。
  •     执行日期和时间算法,可能产生能够唯一、明确标识单个时间点的结果。
    .NET Framework 包括 DateTime、DateTimeOffset 和 TimeZoneInfo 类型,所有这些类型都可用于生成使用日期和时间的应用程序。
    DateTime 结构
    DateTime 值用于定义特定的日期和时间。从 .NET Framework 的 2.0 版本开始,就包括了一个 Kind 属性,该属性可提供有关日期和时间所属时区的有限信息。Kind 属性返回的 DateTimeKind 值指示 DateTime 值是表示本地时间 (DateTimeKind..::.Local)、协调世界时 (UTC) (DateTimeKind..::.Utc),还是表示未指定的时间 (DateTimeKind..::.Unspecified)。
    DateTime 结构适用于执行下列操作的应用程序:
        只使用日期。
        只使用时间。
        使用抽象日期和时间。
        从 .NET Framework 之外的源(如 SQL 数据库)中检索日期和时间信息。这些源通常以与 DateTime 结构兼容的简单格式存储日期和时间信息。
        执行日期和时间算法,但不关心常规结果。例如,在向特定日期和时间添加六个月的加法运算中,结果是否按夏时制进行调整通常并不重要。
    除非是表示 UTC 的特定 DateTime 值,否则,该日期和时间值在可移植性方面通常是不明确或是有限的。例如,如果 DateTime 值表示本地时间,那么它在该本地时区内是可移植的(也就是说,如果在同一时区中的不同系统上反序列化该值,该值仍可以明确标识单个时间点)。在该本地时区之外,该 DateTime 值可有多种解释。如果该值的 Kind 属性为 DateTimeKind..::.Unspecified,那么其可移植性会更低:现在它在同一时区内不明确,那么它在首次被序列化的同一系统上,可能更不明确。只有表示 UTC 的 DateTime 值才可以明确标识单个时间点,且与它在哪个系统或是哪个时区中使用无关。
    重要说明: 在保存或共享 DateTime 数据时,应使用 UTC,而且应将 DateTime 值的 Kind 属性设置为 DateTimeKindUTC()()()。
 
    DateTimeOffset 结构
    DateTimeOffset 结构表示日期和时间值以及指示该值与 UTC 之差的偏移量。因此,该值始终可以明确标识单个时间点。
    虽然 DateTimeOffset 类型包括 DateTime 类型的大部分功能,但其目的并不是为了在应用程序开发中替代 DateTime 类型。而是适用于执行下列操作的应用程序:
        唯一、明确地标识单个时间点。DateTimeOffset 类型可用于明确定义“现在”的含义、记录事务次数、记录系统或应用程序事件的次数,以及记录文件创建和修改的次数。
        执行常规的日期和时间算法。
        保留多个相关时间,只要这些时间作为两个单独的值或作为一个结构的两个成员存储即可。
    注意: DateTimeOffset 值的这些用法要比 DateTime 值的用法更为常见。因此,应考虑将 DateTimeOffset 作为应用程序开发的默认日期和时间类型。
 
    TimeZoneInfo 类
    TimeZoneInfo 类表示世界上的任意时区,并能将一个时区中的任何日期和时间转换为另一个时区中的等效日期和时间。通过 TimeZoneInfo 类,可以使用日期和时间,以便任何日期和时间值都可以明确标识单个时间点。TimeZoneInfo 类还是可扩展的。虽然它依赖于在注册表中定义的、为 Windows 系统提供的时区信息,但它支持创建自定义时区。它还支持时区信息的序列化和反序列化。
    在有些情况下,完全利用 TimeZoneInfo 类可能需要进一步的开发工作。首先,日期和时间值与其所属的时区没有紧密关联。因此,除非您的应用程序提供将日期和时间与其相关联的时区链接在一起的某种机制,否则特定的日期和时间值很容易解除与其时区的关联。(链接此信息的一种方法是定义同时包含日期和时间值及其相关联的时区对象的类或结构。) 其次,Windows XP 及 Windows 的早期版本没有提供对历史时区信息的实时支持,而 Windows Vista 只能提供有限的支持。对于设计用于处理历史日期和时间的应用程序,必须广泛使用自定义时区。
    只有在实例化日期和时间对象时已知该日期和时间值所属时区的情况下,才可以利用 .NET Framework 中提供的时区支持。但通常情况并非如此,特别是在 Web 或网络应用程序中。


和时区相关的操作

    TimeZoneInfo 类不公开公共构造函数。因此,new 关键字不能用于创建新的 TimeZoneInfo 对象。应改为通过从注册表中检索有关预定义时区的信息或创建自定义时区来实例化 TimeZoneInfo 对象。本主题讨论如何通过注册表中存储的数据实例化时区。此外,TimeZoneInfo 类的 static(在 Visual Basic 中为 shared)属性还提供对协调世界时 (UTC) 和本地时区的访问。
    枚举计算机上存在的时区
        foreach (TimeZoneInfo z in TimeZoneInfo.GetSystemTimeZones())
            {
            Console.WriteLine(z.StandardName);
            }
    访问预定义的 UTC 和本地时区对象
        访问协调世界时 (UTC) TimeZoneInfo 对象
            使用 static TimeZoneInfo.Utc 属性访问协调世界时。
            不要将该属性返回的 TimeZoneInfo 对象分配给对象变量,而是继续通过 TimeZoneInfo.Utc 属性访问协调世界时。
        访问本地时区
            使用 static(在 Visual Basic 中为 Shared)TimeZoneInfo.Local 属性访问本地系统时区。
            不要将该属性返回的 TimeZoneInfo 对象分配给对象变量,而是继续通过 TimeZoneInfo.Local 属性访问本地时区。
   
    实例化 TimeZoneInfo 对象
        声明一个 TimeZoneInfo 对象。
        调用 static(在 Visual Basic 中为 Shared)TimeZoneInfo.FindSystemTimeZoneById 方法。
        处理由该方法引发的任何异常,特别是注册表中未定义该时区时引发的 TimeZoneNotFoundException。
   
    保存和还原时区
    TimeZoneInfo 类依赖注册表检索预定义的时区数据。但是,注册表是一个动态结构。此外,注册表包含的时区信息主要供操作系统在处理当前年份的时间调整和转换时使用。对于依赖准确时区数据的应用程序来说,这有两个主要的影响:
        注册表中可能未定义应用程序需要的时区,或者该时区可能已被重命名或从注册表中移除。
        注册表中定义的时区可能缺少执行历史时区转换所需的特定调整规则的相关信息。
    时区序列化和反序列化
        在通过序列化和反序列化时区数据来保存和还原时区时,只需执行两次方法调用:
        通过调用 TimeZoneInfo 对象的 ToSerializedString 方法可以序列化该对象。该方法不带任何参数,并会返回一个包含时区信息的字符串。
        通过向 static TimeZoneInfo.FromSerializedString 方法传递一个序列化字符串,可以从该字符串反序列化 TimeZoneInfo 对象。

示例代码:
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading;

namespace  Mytimezone
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            Program p 
= new Program();
            
//p.showTimeZone();
            
//p.ShowDateTime();
            
//p.ShowDateTimeOffset();
            Console.ReadLine();
        }

        
public void ShowDateTime()
        
{
            DateTime day 
= DateTime.Now;
            Console.WriteLine(day);
            Console.WriteLine(day.Kind);
            Console.WriteLine(DateTime.Today);
            Console.WriteLine(DateTime.Now.TimeOfDay);
            Console.WriteLine(DateTime.Now.Date);
            Console.WriteLine(
string.Format("UTC Time:{0}", DateTime.Now.ToUniversalTime().ToString()));
            
// DateTimeOffset.
        }

        
public void ShowDateTimeOffset()
        
{
            Console.WriteLine(DateTimeOffset.Now);
            Console.WriteLine(DateTimeOffset.UtcNow);
            Console.WriteLine(DateTimeOffset.Now.Offset);
        }


        
public void showTimeZone()
        
{
            Console.WriteLine(
string.Format("Local TimeZoneInfo {0}", TimeZoneInfo.Local.StandardName)); //鏄剧ず鏈湴鏃跺尯鍚嶇О
            Console.WriteLine(string.Format("Local UTC {0}", TimeZoneInfo.Utc.StandardName));
            
foreach (TimeZoneInfo z in TimeZoneInfo.GetSystemTimeZones())
            
{
                Console.WriteLine(z.StandardName);
            }

            TimeZoneInfo easternZone 
= TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");    //瀹炰緥鍖?TimeZoneInfo 瀵硅薄
            Console.WriteLine(easternZone.BaseUtcOffset);

        }

    }

}


参考:
    http://msdn.microsoft.com/zh-cn/library/bb384268.aspx
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值