如何从互联网上获取DateTime?
如何从互联网或服务器使用C#获取当前的date和时间? 我想花时间如下:
public static DateTime GetNetworkTime (string ntpServer) { IPAddress[] address = Dns.GetHostEntry(ntpServer).AddressList; if (address == null || address.Length == 0) throw new ArgumentException("Could not resolve ip address from '" + ntpServer + "'.", "ntpServer"); IPEndPoint ep = new IPEndPoint(address[0], 123); return GetNetworkTime(ep); }
我作为netServer
传递服务器的IP地址,但它不能正常工作。
对于13号端口被阻塞的环境,NIST的时间可以按如下方式进行网页抓取,
public static DateTime GetNistTime() { DateTime dateTime = DateTime.MinValue; HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://nist.time.gov/actualtime.cgi?lzbc=siqm9b"); request.Method = "GET"; request.Accept = "text/html, application/xhtml+xml, */*"; request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)"; request.ContentType = "application/x-www-form-urlencoded"; request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); //No caching HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { StreamReader stream = new StreamReader(response.GetResponseStream()); string html = stream.ReadToEnd();//<timestamp time=\"1395772696469995\" delay=\"1395772696469995\"/> string time = Regex.Match(html, @"(?<=\btime="")[^""]*").Value; double milliseconds = Convert.ToInt64(time) / 1000.0; dateTime = new DateTime(1970, 1, 1).AddMilliseconds(milliseconds).ToLocalTime(); } return dateTime; }
以下是可用于从NIST Internet时间服务中检索时间的代码示例
var client = new TcpClient("time.nist.gov", 13); using (var streamReader = new StreamReader(client.GetStream())) { var response = streamReader.ReadToEnd(); var utcDateTimeString = response.Substring(7, 17); var localDateTime = DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); }
这是一个快速的代码,可以从头文件中获取时间,而不需要端口13
public static DateTime GetNistTime() { var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com"); var response = myHttpWebRequest.GetResponse(); string todaysDates = response.Headers["date"]; return DateTime.ParseExact(todaysDates, "ddd, dd MMM yyyy HH:mm:ss 'GMT'", CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal); }
事情可能会出错。 上面创build的代码的所有实现都容易出错。 有时,它有效,有时它会导致WebExpection错误消息。
更好的实现:
try{ using (var response = WebRequest.Create("http://www.google.com").GetResponse()) //string todaysDates = response.Headers["date"]; return DateTime.ParseExact(response.Headers["date"], "ddd, dd MMM yyyy HH:mm:ss 'GMT'", CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal); } catch (WebException) { return DateTime.Now; //In case something goes wrong. }
结论:
让您的Web应用程序依赖提供准确date信息的服务至关重要。 我用我的应用程序中创build的代码之一,它真的搞砸了。
首先检查http://tf.nist.gov/tf-cgi/servers.cgi上的可用服务器;
public static DateTime GetServerTime() { var result = DateTime.Now; // Initialize the list of NIST time servers // http://tf.nist.gov/tf-cgi/servers.cgi string[] servers = new string[] { "time-c.nist.gov", "time-d.nist.gov", "nist1-macon.macon.ga.us", "wolfnisttime.com", "nist.netservicesgroup.com", "nisttime.carsoncity.k12.mi.us", "nist1-lnk.binary.net", "wwv.nist.gov", "time.nist.gov", "utcnist.colorado.edu", "utcnist2.colorado.edu", "nist-time-server.eoni.com", "nist-time-server.eoni.com" }; Random rnd = new Random(); foreach (string server in servers.OrderBy(x => rnd.NextDouble()).Take(9)) { try { // Connect to the server (at port 13) and get the response. Timeout max 1second string serverResponse = string.Empty; var tcpClient = new TcpClient(); if (tcpClient.ConnectAsync(server, 13).Wait(1000)) { using (var reader = new StreamReader(tcpClient.GetStream())) { serverResponse = reader.ReadToEnd(); } } // If a response was received if (!string.IsNullOrEmpty(serverResponse)) { // Split the response string ("55596 11-02-14 13:54:11 00 0 0 478.1 UTC(NIST) *") string[] tokens = serverResponse.Split(' '); // Check the number of tokens if (tokens.Length >= 6) { // Check the health status string health = tokens[5]; if (health == "0") { // Get date and time parts from the server response string[] dateParts = tokens[1].Split('-'); string[] timeParts = tokens[2].Split(':'); // Create a DateTime instance DateTime utcDateTime = new DateTime( Convert.ToInt32(dateParts[0]) + 2000, Convert.ToInt32(dateParts[1]), Convert.ToInt32(dateParts[2]), Convert.ToInt32(timeParts[0]), Convert.ToInt32(timeParts[1]), Convert.ToInt32(timeParts[2])); // Convert received (UTC) DateTime value to the local timezone result = utcDateTime.ToLocalTime(); return result; // Response successfully received; exit the loop } } } } catch { // Ignore exception and try the next server } } return result; }
同一个想法的另一个版本:
public static class InternetTime { public static DateTimeOffset? GetCurrentTime() { using (var client = new HttpClient()) { try { var result = client.GetAsync("https://google.com", HttpCompletionOption.ResponseHeadersRead).Result; return result.Headers.Date; } catch { return null; } } } }
这里HttpCompletionOption.ResponseHeadersRead
用于防止加载其余的响应,因为我们只需要HTTP头文件。
使用InternetTime.GetCurrentTime().Value.ToLocalTime()
获取当前的本地时间。
生成一个属性LogTime
public DateTime LogTime { get; set; }
根据需要拨打该方法。 目前我正在返回一个布尔types
bool IsDateTimeAvailable = await GetDateTimeFromServer(); if (IsDateTimeAvailable) await DisplayAlert("Success", "Date and Time successfully retrieved from server","OK");
函数定义是休闲的
private async Task<bool> GetDateTimeFromServer() { using (var client = new HttpClient()) { HttpResponseMessage response = null; try { response = await client.GetAsync("https://time.is/India"); } catch (Exception ex) { Debug.WriteLine(ex.Message); return false; } if (response.IsSuccessStatusCode) { DateTimeOffset? currenttime = response.Content.Headers.Expires; LogTime = currenttime.Value.LocalDateTime; return true; } } return false; }