• .Net2.0下获取世界各时区信息及夏令时信息


    在.Net 3.5下有一个TimeZoneInfo类,可以很方便的转换时区和进行时间转换.但是在.Net 2.0下,只能对当前服务器时区进行处理,十分不方便.特别系统是世界范围使用的,更需要考虑当地时区特别是夏令时的问题,不然时间就会错乱.如何解决这个问题,就要通过自己手动处理了.

    其实Windows的时区信息都存放在Windows注册表的"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"下.只要读取相关信息出来.就能实现和TimeZoneInfo相同的功能.下边我们就通过一个小demo.读取世界时区信息,计算时区偏移量和夏令时偏移量.并根据用户选择的时区和输入时间,判断该时间是否属于该时区的夏令时范围.

    首先,我们需要创建两个Struct来记录相关信息,一个是SytemTime,一个TimeZoneInformation.代码如下:

    SystemTime Struct
    TimeZoneInformation Struct

    定义好相关Structs后,我们就可以读取注册表了.先定义几个读取注册表的方法:

    RegistryKey Code
    private static RegistryKey GetTimeZoneRegistryKey()
    {
        RegistryKey key 
    = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"false);
        
    if (key == null)
            
    throw new KeyNotFoundException(@"Cannot find the windows registry key (Time Zone).");
        
    else
            
    return key;
    }

    private static RegistryKey GetTimeZoneRegistrySubKey(string zoneId)
    {
        RegistryKey key 
    = GetTimeZoneRegistryKey();
        RegistryKey subKey 
    = key.OpenSubKey(zoneId, false);
        
    if (subKey == null)
            
    throw new Exception("Unknown time zone.");
        
    else
            
    return subKey;
    }

    private static RegistryKey GetTimeZoneRegistryDynamicSubKey(TimeZoneInfo tzi)
    {
        RegistryKey subKey 
    = GetTimeZoneRegistrySubKey(tzi._id);
        
    return subKey.OpenSubKey("Dynamic DST"false);
    }

    下边我们开始读取注册表各个TimeZone信息

    TimeZones Code
    public static TimeZoneInfo[] GetTimeZones()
    {
        List
    <TimeZoneInfo> tzInfos = new List<TimeZoneInfo>();
        RegistryKey key 
    = GetTimeZoneRegistryKey();
        
    foreach (string zoneName in key.GetSubKeyNames())
        {
            TimeZoneInfo tzi 
    = new TimeZoneInfo();
            tzi._id 
    = zoneName;
            tzi.SetValues();
            tzInfos.Add(tzi);
        }
        TimeZoneInfo.Sort(tzInfos);
        
    return tzInfos.ToArray();
    }

    可以看到上述代码是循环读取注册表里面的信息,通过SetVales方法放到一个List:

    SetValues
    private void SetValues()
    {
        RegistryKey subKey 
    = GetTimeZoneRegistrySubKey(this._id);
        
    this._displayName = subKey.GetValue("Display").ToString();
        
    this._tzi.daylightName = subKey.GetValue("Dlt").ToString();
        
    this._tzi.standardName = subKey.GetValue("Std").ToString();
        
    this._tzi.SetBytes(subKey.GetValue("Tzi"as byte[]);
    }

    通过简单的读取信息填入TimeZoneInfo List,在页面级别我们就可以简单用下面的方法来显示给用户选择:

    UI1
    TimeZoneInfo[] TimeZones = TimeZoneInfo.GetTimeZones();
    this.drpList.DataSource = TimeZones;
    this.drpList.DataTextField = "DisplayName";
    this.drpList.DataValueField = "Id";
    this.drpList.DataBind();

    当用选择了某一个时区,我们就可以根据用户选择的时区和输入的日期显示相关时区信息:

    UI2
    if (tzi.DisplayName == this.drpList.SelectedItem.Text)
    {
        DateTime dtDate 
    = DateTime.Parse(this.txtDate.Text.Trim());
        
    this.lblInfo.Text += string.Format("<br />时区ID:  {0} ", tzi.Id);
        
    this.lblInfo.Text += string.Format("<br />显示名称:  {0} ", tzi.DisplayName);
        
    this.lblInfo.Text += string.Format("<br />标准名称:  {0} ", tzi.StandardName);
        
    this.lblInfo.Text += string.Format("<br /><br />当前时间是否夏令时:  {0} ", tzi.IsDaylightSavingTime(dtDate).ToString());
        
    this.lblInfo.Text += string.Format("<br />夏令时名称:  {0} ", tzi.DaylightName(dtDate));
        
    this.lblInfo.Text += string.Format("<br />基本偏移量:  {0} ", tzi.StandardUtcOffset.ToString());
        
    this.lblInfo.Text += string.Format("<br />当前偏移量:  {0} ", tzi.GetCurrentUtcOffset(dtDate).ToString());
        DaylightTime dt 
    = tzi.GetDaylightChanges(dtDate.Year);
        
    this.lblInfo.Text += string.Format("<br />夏令时开始时间:  {0} ", dt.Start.ToString("yyyy-MM-dd HH:mm:ss"));
        
    this.lblInfo.Text += string.Format("<br />夏令时结束时间:  {0} ", dt.End.ToString("yyyy-MM-dd HH:mm:ss"));
        
    this.lblInfo.Text += string.Format("<br />夏令时增量:  {0} ", dt.Delta.ToString());
    }

    更详细的东西就不废话了.附上完整的Demo给大家看吧:

    下载Demo点击这里

  • 相关阅读:
    [蓝桥杯] 第39级台阶
    [蓝桥杯] 马虎的算式
    POJ 1142 Smith Numbers(史密斯数)
    HDU 1181 变形课
    HDU 1728 逃离迷宫
    HDU 2188 悼念512汶川大地震遇难同胞――选拔志愿者 巴什博奕
    HDU 2177 取(2堆)石子游戏 (威佐夫博弈)
    HDU 1847 Good Luck in CET-4 Everybody! 博弈
    HDU 1525 Euclid's Game
    HDU 1517 A Multiplication Game 博弈
  • 原文地址:https://www.cnblogs.com/KenBlove/p/1357493.html
Copyright © 2020-2023  润新知