用C#获取NIST时间
NIST为National Institute of Standards and Technology(美国技术标准局)的缩写,他们发布了一些时间的服务,而且这些时间服务的返回格式都非常简洁,便于网络应用。
首先,在网络上找到了这个文章,http://www.360doc.com/content/10/1120/01/2482712_70833596.shtml,使用的是基于www.time.gov这个网页通过正则表达式来匹配找到时间。其实这个方法是变相的用在网页内找时间的方法,只要在能够提供时间的网站上都可以进行,也不失为一种不错的方法,但有更高效的方法。
NIST发布了很多Internet Time Service,列表在http://tf.nist.gov/tf-cgi/servers.cgi,端口为13。注意,即使是网站上公布的可用的IP也最好经过验证后使用,在国内不一定可用。在网页中输入http://131.107.13.100:13就可以得到类似于57423 16-02-05 15:14:25 00 0 0 455.0 UTC(NIST) * 这样的字符串,经过解析之后就可以得到正确的时间。
下面把自己编写的类分享给大家。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
public class TimeHelper { //Number of seconds如果系统时间和NIST的时间相差此值以上表明系统时间不正确 private const int THRESHOLD_SECONDS = 60; //Server IP addresses from NIST Internet Time Servers private static string[] Servers = { "131.107.13.100", "98.175.203.200", "216.229.0.179", "128.138.141.172", "198.60.73.8", "216.228.192.69", "64.113.32.5",//可以使用,不稳定 "24.56.178.140",//可以使用,不稳定 "time.nist.gov", "129.6.15.30", "128.138.140.44", }; public static string LastHost = ""; public static DateTime LastSysTime; public static DateTime GetTime(WebProxy proxy = null) { //Returns UTC/GMT using an NIST server if possible, // degrading to simply returning the system clock //If we are successful in getting NIST time, then // LastHost indicates which server was used and // LastSysTime contains the system time of the call // If LastSysTime is not within 15 seconds of NIST time, // the system clock may need to be reset // If LastHost is "", time is equal to system clock string host = null; DateTime result = default(DateTime); LastHost = ""; foreach (string host_loopVariable in Servers) { host = host_loopVariable; result = GetNISTTime(host, proxy); if (result > DateTime.MinValue) { LastHost = host; break; // TODO: might not be correct. Was : Exit For } } if (string.IsNullOrEmpty(LastHost)) { //No server in list was successful so use system time throw new Exception("All servers is unreachable!"); //result = DateTime.UtcNow; } return result; } public static bool WindowsClockIncorrect(WebProxy proxy = null) { DateTime nist = GetTime(proxy); if ((Math.Abs((nist - LastSysTime).Seconds) > THRESHOLD_SECONDS)) { return true; } return false; } private static DateTime GetNISTTime(string host, WebProxy proxy = null) { //Returns DateTime.MinValue if host unreachable or does not produce time //DateTime result = default(DateTime); string timeStr = null; try { //WebClient wc = new WebClient(); //wc.Headers.Set(System.Net.HttpRequestHeader.UserAgent, " Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3"); //wc.Proxy = WebHelper.getProxy(); //string uri = "http://" + host + ":13"; //Stream stream = wc.OpenRead(uri); //StreamReader sr = new StreamReader(stream); //timeStr = sr.ReadToEnd(); //wc.Dispose(); //sr.Close(); HttpWebRequest rq = (HttpWebRequest)HttpWebRequest.Create("http://" + host + ":13"); rq.Proxy = proxy; rq.Method = "CONNECT"; HttpWebResponse rp = (HttpWebResponse)rq.GetResponse(); var st = new StreamReader(rp.GetResponseStream()); timeStr = st.ReadToEnd(); st.Close(); //StreamReader reader = new StreamReader(new TcpClient(host, 13).GetStream()); //LastSysTime = DateTime.UtcNow; //timeStr = reader.ReadToEnd(); //reader.Close(); } //catch (SocketException ex) //{ // //Couldn't connect to server, transmission error // Debug.WriteLine("Socket Exception [" + host + "]"); // return DateTime.MinValue; //} catch (Exception ex) { //Some other error, such as Stream under/overflow return DateTime.MinValue; } //Parse timeStr if ((timeStr.Substring(38, 9) != "UTC(NIST)")) { //This signature should be there return DateTime.MinValue; } if ((timeStr.Substring(30, 1) != "0")) { //Server reports non-optimum status, time off by as much as 5 seconds return DateTime.MinValue; //Try a different server } int jd = int.Parse(timeStr.Substring(1, 5)); int yr = int.Parse(timeStr.Substring(7, 2)); int mo = int.Parse(timeStr.Substring(10, 2)); int dy = int.Parse(timeStr.Substring(13, 2)); int hr = int.Parse(timeStr.Substring(16, 2)); int mm = int.Parse(timeStr.Substring(19, 2)); int sc = int.Parse(timeStr.Substring(22, 2)); if ((jd < 15020)) { //Date is before 1900 return DateTime.MinValue; } if ((jd > 51544)) yr += 2000; else yr += 1900; return new DateTime(yr, mo, dy, hr, mm, sc); } } |
很多注释和测试代码也没有删除,分享给大家。把源码也分享给大家:
说点什么