54 votes

Comment obtenir DateTime sur Internet ?

Comment obtenir la date et l'heure actuelles à partir d'Internet ou d'un serveur en utilisant C# ? J'essaye d'avoir le temps comme suit :

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

Je transmets l'adresse IP du serveur sous la forme netServer , mais cela ne fonctionne pas correctement.

56voto

Nemo Points 456

Pour les environnements où le port 13 est bloqué, l'heure du NIST peut être récupérée sur le Web comme ci-dessous,

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

44voto

Alex Aza Points 29204

Voici un exemple de code que vous pouvez utiliser pour récupérer l'heure du NIST Internet Time Service

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

42voto

glienart Points 531

Voici un code rapide pour obtenir l'heure de l'en-tête, fonctionne sans avoir besoin du port 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);
}

14voto

cerberus Points 80

Les choses pourraient mal tourner. Toutes les implémentations du code fondé ci-dessus sont sujettes aux erreurs. Parfois, cela fonctionne et parfois cela génère un message d'erreur WebExpection.

Une meilleure mise en œuvre :

         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. 
        }

Conclusion:

Il est essentiel que votre application Web dépende d'un service fournissant des informations de date précises. J'ai utilisé l'un des codes trouvés ici dans mon application et cela gâche vraiment les choses.

9voto

dodbrian Points 402

Une autre version de la même idée :

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

Ici, HttpCompletionOption.ResponseHeadersRead est utilisé pour empêcher le chargement du reste de la réponse, car nous n'avons besoin que des en-têtes HTTP.

Utilisez InternetTime.GetCurrentTime().Value.ToLocalTime() pour obtenir l'heure locale actuelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X