Getting current GMT time
Asked Answered
F

6

48

Is there a method in C# that returns the UTC (GMT) time zone? Not based on the system's time.

Basically I want to get the correct UTC time even if my system time is not right.

Flank answered 5/2, 2009 at 16:55 Comment(3)
Just a quick note: UTC time and GMT time are not always the same thing. UTC is easy in .net, GMT less so.Jennette
@Jekke - Well, they never get far out... < 1s IIRC...Skycap
Why can't you rely on the system having the right time synchronized over NTP?Israelitish
C
54

Instead of calling

DateTime.Now.ToUniversalTime()

you can call

DateTime.UtcNow

Same thing but shorter :) Documentation here.

Caughey answered 12/3, 2012 at 15:30 Comment(1)
This is based on system time looking at the docs? Gets a DateTime object that is set to the current date and time on this computer, expressed as the Coordinated Universal Time (UTC). The question was how to get time in UTC without relying on the system clock. Obviously I'm confused.Ballroom
P
20

Not based on the system's time? You'd need to make a call to a network time service or something similar. You could write an NTP client, or just screenscrape World Clock ;)

I don't believe .NET has an NTP client built in, but there are quite a few available.

Puerperal answered 5/2, 2009 at 16:59 Comment(0)
U
7

I use this from 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;
}
Univalence answered 20/1, 2012 at 12:15 Comment(4)
You may want to use pool.ntp.org to let it choose a server for youVedavedalia
Ah, that makes sense. Easier than my chooser.Univalence
@Vedavedalia I tried to use your idea. But , it didn't work. I got the error message "No connection could be made because the target machine actively refused it 140.109.1.10:13""Magdalenamagdalene
@prabhakaran: Try UDP, not TCP. Or 0.pool.ntp.orgVedavedalia
M
3

If I were to wager a guess for how to get a guaranteed accurate time, you'd have to find / write some NNTP class to get the time off of a time server.

If you search C# NTP on google you can find a few implementations, otherwise check the NTP protocol.

Manville answered 5/2, 2009 at 17:0 Comment(0)
E
3

If your system time is not right, nothing that you get out of the DateTime class will help. Your system can sync the time with time servers though, so if that is turned on, the various DateTime UTC methods/properties will return the correct UTC time.

Enschede answered 5/2, 2009 at 17:1 Comment(0)
X
0

You can simply hardcode a base DateTime in and calculate the difference between your given DateTime with that base to determine the precise desired DateTime as below code:

    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);   

The output of above code is as follow:

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
X answered 18/11, 2020 at 8:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.