1 using System;
2 using System.Net;
3 using System.Net.Sockets;
4 using System.Runtime.InteropServices;
5 using System.Text;
6 using System.Windows.Threading;
7
8 namespace 获取网络时间
9 {
10 /// <summary>
11 /// 使用time.nist.gov可靠性好
12 ///
13 /// </summary>
14 public class DateTimeHelper
15 {
16 [DllImport("kernel32.dll")]
17 private static extern bool SetLocalTime(ref Systemtime time);
18
19 [StructLayout(LayoutKind.Sequential)]
20 private struct Systemtime
21 {
22 public short year;
23 public short month;
24 public short dayOfWeek;
25 public short day;
26 public short hour;
27 public short minute;
28 public short second;
29 public short milliseconds;
30 }
31
32 /// <summary>
33 /// 设置系统时间
34 /// </summary>
35 /// <param name="dt">需要设置的时间</param>
36 /// <returns>返回系统时间设置状态,true为成功,false为失败</returns>
37 public static bool SetLocalDateTime(DateTime dt)
38 {
39 Systemtime st;
40
41 st.year = (short)dt.Year;
42 st.month = (short)dt.Month;
43 st.dayOfWeek = (short)dt.DayOfWeek;
44 st.day = (short)dt.Day;
45 st.hour = (short)dt.Hour;
46 st.minute = (short)dt.Minute;
47 st.second = (short)dt.Second;
48 st.milliseconds = (short)dt.Millisecond;
49 bool rt = SetLocalTime(ref st);
50 return rt;
51 }
52
53
54 public static DateTime GetDateTime(long timeStamp)
55 {
56 return new DateTime(1970, 1, 1).AddSeconds(timeStamp).ToLocalTime();
57 }
58
59 public static bool GetInternetTime(string url, out DateTime dt, out string errMsg)
60 {
61 dt = DateTime.MinValue;
62 var startDt = DateTime.Now;
63 var port = 13;
64 var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 2000 };
65 try
66 {
67 var iphostinfo = Dns.GetHostEntry(url);
68 var ip = iphostinfo.AddressList[0];
69 var ipe = new IPEndPoint(ip, port);
70
71 var iar = socket.BeginConnect(ipe, null, null);
72 if (!iar.AsyncWaitHandle.WaitOne(5000))
73 {
74 errMsg = "连接超时" + url;
75 return false;
76 }
77 var recvBuffer = new byte[1024];
78 var sb = new StringBuilder();
79 var myE = Encoding.UTF8;
80
81 int nBytes;
82 while ((nBytes = socket.Receive(recvBuffer, 0, 1024, SocketFlags.None)) > 0)
83 {
84 sb.Append(myE.GetString(recvBuffer, 0, nBytes));
85 }
86 var o = sb.ToString().Split(' ');
87
88
89 TimeSpan ts = DateTime.Now - startDt;
90
91 var setDt = Convert.ToDateTime(o[1] + " " + o[2]).Subtract(-ts); // 减去中途消耗的时间
92
93
94 dt = setDt.ToLocalTime();
95 Console.WriteLine(@"服务器:{0}时间:{1}", url, setDt);
96 errMsg = "";
97 return true;
98 }
99 catch (Exception ex)
100 {
101
102 errMsg = ex.Message;
103 return false;
104 }
105 finally
106 {
107 socket.Close();
108 }
109 }
110
111 /// <summary>
112 /// 调用示例
113 /// </summary>
114 private static void ExamTest()
115 {
116 var ok = false;
117 var errMsg = "";
118 var dt = DateTime.MinValue;
119 var url = "time.nist.gov";
120 Action a = delegate
121 {
122 if (string.IsNullOrEmpty(url)) return;
123
124 ok = DateTimeHelper.GetInternetTime(url, out dt, out errMsg);
125 };
126 a.BeginInvoke(_ =>
127 {
128 Action b = delegate
129 {
130 if (ok)
131 {
132 var success = DateTimeHelper.SetLocalDateTime(dt);
133 if (success)
134 {
135 string infoTxt = "更新时间成功:" + dt;
136 }
137 }
138 else
139 {
140 string errInfo = "更新出错:" + errMsg;
141 }
142 };
143 }, null);
144 }
145 }
146 }
private void SetTimeBtn_Click(object sender, RoutedEventArgs e)
{
SettimeBtn.IsEnabled = false;
var ok = false;
var errMsg = "";
var dt = DateTime.MinValue;
var url = SvrCombox.Text;
Action a = delegate
{
if (string.IsNullOrEmpty(url)) return;
ok = DateTimeHelper.GetInternetTime(url, out dt, out errMsg);
};
a.BeginInvoke(_ =>
{
Dispatcher.Invoke(() =>
{
SettimeBtn.IsEnabled = true;
if (ok)
{
var success = DateTimeHelper.SetLocalDateTime(dt);
if (success)
{
InfoText.Text = "更新时间成功:" + dt;
}
}
else
{
InfoText.Text = "更新出错:" + errMsg;
}
});
}, null);
}