获得当前的GMT时间

时间:2009-02-05 16:55:30

标签: c# .net timezone utc ntp

C#中是否有返回UTC(GMT)时区的方法?不是基于系统的时间。

基本上我想获得正确的UTC时间,即使我的系统时间不对。

6 个答案:

答案 0 :(得分:35)

而不是打电话

DateTime.Now.ToUniversalTime()

你可以打电话

DateTime.UtcNow

相同但更短:)文档here

答案 1 :(得分:18)

不是基于系统的时间?您需要拨打网络时间服务或类似的东西。你可以写一个NTP客户端,或只是屏幕抓取World Clock;)

我不相信.NET内置了NTP客户端,但有quite a few available

答案 2 :(得分:7)

我在UNITY中使用它

//Get a NTP time from NIST
//do not request a nist date more than once every 4 seconds, or the connection will be refused.
//more servers at tf.nist.goc/tf-cgi/servers.cgi
public static DateTime GetDummyDate()
{
    return new DateTime(1000, 1, 1); //to check if we have an online date or not.
}
public static DateTime GetNISTDate()
{
    Random ran = new Random(DateTime.Now.Millisecond);
    DateTime date = GetDummyDate();
    string serverResponse = string.Empty;

    // Represents the list of NIST servers
    string[] servers = new string[] {
        "nist1-ny.ustiming.org",
        "time-a.nist.gov",
        "nist1-chi.ustiming.org",
        "time.nist.gov",
        "ntp-nist.ldsbc.edu",
        "nist1-la.ustiming.org"                         
    };

    // Try each server in random order to avoid blocked requests due to too frequent request
    for (int i = 0; i < 5; i++)
    {
        try
        {
            // Open a StreamReader to a random time server
            StreamReader reader = new StreamReader(new System.Net.Sockets.TcpClient(servers[ran.Next(0, servers.Length)], 13).GetStream());
            serverResponse = reader.ReadToEnd();
            reader.Close();

            // Check to see that the signature is there
            if (serverResponse.Length > 47 && serverResponse.Substring(38, 9).Equals("UTC(NIST)"))
            {
                // Parse the date
                int jd = int.Parse(serverResponse.Substring(1, 5));
                int yr = int.Parse(serverResponse.Substring(7, 2));
                int mo = int.Parse(serverResponse.Substring(10, 2));
                int dy = int.Parse(serverResponse.Substring(13, 2));
                int hr = int.Parse(serverResponse.Substring(16, 2));
                int mm = int.Parse(serverResponse.Substring(19, 2));
                int sc = int.Parse(serverResponse.Substring(22, 2));

                if (jd > 51544)
                    yr += 2000;
                else
                    yr += 1999;

                date = new DateTime(yr, mo, dy, hr, mm, sc);

                // Exit the loop
                break;
            }
        }
        catch (Exception ex)
        {
            /* Do Nothing...try the next server */
        }
    }
return date;
}

答案 3 :(得分:3)

如果我打算猜测如何获得有保证的准确时间,你必须找/写一些NNTP类来获得时间服务器的时间。

如果您在Google上搜索C# NTP,则可以找到一些implementations,否则请查看NTP协议。

答案 4 :(得分:1)

如果您的系统时间不正确,那么您从DateTime类中获得的任何内容都无济于事。您的系统可以将时间与时间服务器同步,因此如果打开它,各种DateTime UTC方法/属性将返回正确的UTC时间。

答案 5 :(得分:1)

您可以简单地硬编码一个基本的DateTime并计算给定的DateTime与该基本之间的差,从而确定所需的精确DateTime,如下所示:

    string format = "ddd dd MMM yyyy HH:mm:ss";     
    string utcBaseStr = "Wed 18 Nov 2020 07:31:34";
    string newyorkBaseStr = "Wed 18 Nov 2020 02:31:34";     
    string nowNewyorkStr = "Wed 18 Nov 2020 03:06:47";
    
    DateTime newyorkBase = DateTime.ParseExact(newyorkBaseStr, format, CultureInfo.InvariantCulture);
    DateTime utcBase = DateTime.ParseExact(utcBaseStr, format, CultureInfo.InvariantCulture);
    DateTime now = DateTime.ParseExact(nowNewyorkStr, format, CultureInfo.InvariantCulture);
    
    var diffMiliseconds = (now - newyorkBase).TotalMilliseconds;
    DateTime nowUtc = utcBase.AddMilliseconds(diffMiliseconds);
    
    Console.WriteLine("Newyork Base = " + newyorkBase);     
    Console.WriteLine("UTC Base = " + utcBase);
    Console.WriteLine("Newyork Now = " + now);      
    Console.WriteLine("Newyork UTC = " + nowUtc);   

以上代码的输出如下:

Newyork Base = 11/18/2020 2:31:34 AM
UTC Base = 11/18/2020 7:31:34 AM
Newyork Now = 11/18/2020 3:06:47 AM
Newyork UTC = 11/18/2020 8:06:47 AM