C# 调用windows时间同步服务获取准确时间

Stella981
• 阅读 417
//创建一个Daytime类代码如下:using System;  
using System.Collections;  
using System.Collections.Generic;  
using System.Data;  
using System.Diagnostics;  
using System.IO;  
using System.Net;  
using System.Net.Sockets;  
using System.Runtime.InteropServices;  
  
public class Daytime  
{  
    // Internet Time Server class by Alastair Dallas 01/27/04  
  
    // Number of seconds  
    private const int THRESHOLD_SECONDS = 15;  
    // that Windows clock can deviate from NIST and still be okay  
  
    //Server IP addresses from   
    //http://www.boulder.nist.gov/timefreq/service/time-servers.html  
    private static string[] Servers = {  
        "129.6.15.28",  
        "129.6.15.29",  
        "132.163.4.101",  
        "132.163.4.102",  
        "132.163.4.103",  
        "128.138.140.44",  
        "192.43.244.18",  
        "131.107.1.10",  
        "66.243.43.21",  
        "216.200.93.8",  
        "208.184.49.9",  
        "207.126.98.204",  
        "205.188.185.33"  
//65.55.21.15time.windows.com微软时间同步服务器
    };  
    public static string LastHost = "";  
  
    public static DateTime LastSysTime;  
    public static DateTime GetTime()  
    {  
        //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);  
            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  
            result = DateTime.UtcNow;  
        }  
  
        return result;  
    }  
  
    public static int SecondsDifference(DateTime dt1, DateTime dt2)  
    {  
        TimeSpan span = dt1.Subtract(dt2);  
        return span.Seconds + (span.Minutes * 60) + (span.Hours * 360);  
    }  
  
    public static bool WindowsClockIncorrect()  
    {  
        DateTime nist = GetTime();  
        if ((Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS))  
        {  
            return true;  
        }  
        return false;  
    }  
  
    private static DateTime GetNISTTime(string host)  
    {  
        //Returns DateTime.MinValue if host unreachable or does not produce time  
        DateTime result = default(DateTime);  
        string timeStr = null;  
  
        try  
        {  
            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);  
    }  
  
    [StructLayout(LayoutKind.Sequential)]  
    public struct SYSTEMTIME  
    {  
        public Int16 wYear;  
        public Int16 wMonth;  
        public Int16 wDayOfWeek;  
        public Int16 wDay;  
        public Int16 wHour;  
        public Int16 wMinute;  
        public Int16 wSecond;  
        public Int16 wMilliseconds;  
    }  
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]  
    private static extern Int32 GetSystemTime(ref SYSTEMTIME stru);  
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]  
    private static extern Int32 SetSystemTime(ref SYSTEMTIME stru);  
  
    public static void SetWindowsClock(DateTime dt)  
    {  
        //Sets system time. Note: Use UTC time; Windows will apply time zone  
  
        SYSTEMTIME timeStru = default(SYSTEMTIME);  
        Int32 result = default(Int32);  
  
        timeStru.wYear = (Int16)dt.Year;  
        timeStru.wMonth = (Int16)dt.Month;  
        timeStru.wDay = (Int16)dt.Day;  
        timeStru.wDayOfWeek = (Int16)dt.DayOfWeek;  
        timeStru.wHour = (Int16)dt.Hour;  
        timeStru.wMinute = (Int16)dt.Minute;  
        timeStru.wSecond = (Int16)dt.Second;  
        timeStru.wMilliseconds = (Int16)dt.Millisecond;  
        result = SetSystemTime(ref timeStru);  
    }  
}  
 


调用方法:
Daytime.GetTime().ToLocalTime()   //这个就是同步后准确的时间,DateTime类型的。
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
3年前
Java日期时间API系列23
  有时候,往往需要统计某个时间区间的销量等问题,这就需要准确的起始时间,获取准确开始时间00:00:00,获取准确结束时间23:59:59。下面增加了一一些方法,获取当天起始时间,昨天起始时间,当前月第一天开始时间,当前月最后一天结束时间,上个月第一天开始时间,上个月最后一天结束时间,某个指定月的起始结束时间等等。其中月份最后一天往往因为月份不同和
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这