时间的处理与网络时间同步

时间准确的重要性不言而喻,有时候我们对时间的要求非常严格,有时候也要求不允许用户调整系统时间,有时候。。。等等情况下,我们都需要时间的同步,虽然Windows也有DOS命令来保持和时钟服务进行同步,但本文另辟途径,介绍另一种获取标准时间并同步时间的操作。

首先,我们来看看一个网站:国家授时中心(http://www.time.ac.cn/stime.asp),这个是应该是时间的权威机构,里面有各国各地的时间,我们可以通过同步该时间来实现系统时间的更新。首先分两步,一步是获取“国家授时中心”的时间,一步是更新系统时间。下面的代码就是做这些工作。

        #region 获取网络时间
        
/// <summary>
        
/// 获取中国国家授时中心网络服务器时间发布的当前时间
        
/// </summary>
        
/// <returns></returns>
        public static DateTime GetChineseDateTime()
        {
            DateTime res 
= DateTime.MinValue;
            
try
            {
                
string url = "http://www.time.ac.cn/stime.asp";
                HttpHelper helper 
= new HttpHelper();
                helper.Encoding 
= Encoding.Default;
                
string html = helper.GetHtml(url);
                
string patDt = @"\d{4}年\d{1,2}月\d{1,2}日";
                
string patHr = @"hrs\s+=\s+\d{1,2}";
                
string patMn = @"min\s+=\s+\d{1,2}";
                
string patSc = @"sec\s+=\s+\d{1,2}";
                Regex regDt 
= new Regex(patDt);
                Regex regHr 
= new Regex(patHr);
                Regex regMn 
= new Regex(patMn);
                Regex regSc 
= new Regex(patSc);

                res 
= DateTime.Parse(regDt.Match(html).Value);
                
int hr = GetInt(regHr.Match(html).Value, false);
                
int mn = GetInt(regMn.Match(html).Value, false);
                
int sc = GetInt(regSc.Match(html).Value, false);
                res 
= res.AddHours(hr).AddMinutes(mn).AddSeconds(sc);
            }
            
catch { }
            
return res;
        }

        
/// <summary>
        
/// 从指定的字符串中获取整数
        
/// </summary>
        
/// <param name="origin">原始的字符串</param>
        
/// <param name="fullMatch">是否完全匹配,若为false,则返回字符串中的第一个整数数字</param>
        
/// <returns>整数数字</returns>
        private static int GetInt(string origin, bool fullMatch)
        {
            
if (string.IsNullOrEmpty(origin))
            {
                
return 0;
            }
            origin 
= origin.Trim();
            
if (!fullMatch)
            {
                
string pat = @"-?\d+";
                Regex reg 
= new Regex(pat);
                origin 
= reg.Match(origin.Trim()).Value;
            }
            
int res = 0;
            
int.TryParse(origin, out res);
            
return res;
        }
        
#endregion
        #region P/Invoke 设置本地时间

        [DllImport(
"kernel32.dll")]
        
private static extern bool SetLocalTime(ref SYSTEMTIME time);

        [StructLayout(LayoutKind.Sequential)]
        
private struct SYSTEMTIME
        {
            
public short year;
            
public short month;
            
public short dayOfWeek;
            
public short day;
            
public short hour;
            
public short minute;
            
public short second;
            
public short milliseconds;
        }

        
/// <summary>
        
/// 设置本地计算机时间
        
/// </summary>
        
/// <param name="dt">DateTime对象</param>
        public static void SetLocalTime(DateTime dt)
        {
            SYSTEMTIME st;

            st.year 
= (short)dt.Year;
            st.month 
= (short)dt.Month;
            st.dayOfWeek 
= (short)dt.DayOfWeek;
            st.day 
= (short)dt.Day;
            st.hour 
= (short)dt.Hour;
            st.minute 
= (short)dt.Minute;
            st.second 
= (short)dt.Second;
            st.milliseconds 
= (short)dt.Millisecond;

            SetLocalTime(
ref st);
        }

        
#endregion

两步操作就可以搞定时间的同步,测试效果还是不错,不过不建议频繁进行时间的同步处理,间隔一段时间检查一次即可。

如果你有更好的方法,希望大家交流提高。 

主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
  转载请注明出处:
撰写人:伍华聪  http://www.iqidi.com 
    
原文地址:https://www.cnblogs.com/wuhuacong/p/1839331.html