Cómo obtener la hora actual de Internet en Android

Resuelto user1726619 asked hace 54 años • 8 respuestas

Estoy creando una aplicación en la que quiero obtener la hora actual de Internet.

Sé cómo obtener la hora del dispositivo usando System.currentTimeMillis, e incluso después de buscar mucho, no obtuve ninguna idea sobre cómo obtenerla de Internet.

user1726619 avatar Jan 01 '70 08:01 user1726619
Aceptado

Puede obtener la hora de los servidores de hora de Internet utilizando el siguiente programa

import java.io.IOException;

import org.apache.commons.net.time.TimeTCPClient;

public final class GetTime {

    public static final void main(String[] args) {
        try {
            TimeTCPClient client = new TimeTCPClient();
            try {
                // Set timeout of 60 seconds
                client.setDefaultTimeout(60000);
                // Connecting to time server
                // Other time servers can be found at : http://tf.nist.gov/tf-cgi/servers.cgi#
                // Make sure that your program NEVER queries a server more frequently than once every 4 seconds
                client.connect("time.nist.gov");
                System.out.println(client.getDate());
            } finally {
                client.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1. Necesitaría la biblioteca Apache Commons Net para que esto funcione. Descargue la biblioteca y agréguela a la ruta de compilación de su proyecto.

(O también puede utilizar la biblioteca Apache Commons Net recortada aquí: https://www-us.apache.org/dist//commons/net/binaries/commons-net-3.6-bin.tar.gz Esto es suficiente para obtener tiempo de internet)

2.Ejecute el programa. Obtendrás la hora impresa en tu consola.

sunil avatar Oct 25 '2012 10:10 sunil

Aquí hay un método que he creado para ti. Puedes usarlo en tu código.

public String getTime() {
try{
    //Make the Http connection so we can retrieve the time
    HttpClient httpclient = new DefaultHttpClient();
    // I am using yahoos api to get the time
    HttpResponse response = httpclient.execute(new
    HttpGet("http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo"));
    StatusLine statusLine = response.getStatusLine();
    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        out.close();
        // The response is an xml file and i have stored it in a string
        String responseString = out.toString();
        Log.d("Response", responseString);
        //We have to parse the xml file using any parser, but since i have to 
        //take just one value i have deviced a shortcut to retrieve it
        int x = responseString.indexOf("<Timestamp>");
        int y = responseString.indexOf("</Timestamp>");
        //I am using the x + "<Timestamp>" because x alone gives only the start value
        Log.d("Response", responseString.substring(x + "<Timestamp>".length(),y) );
        String timestamp =  responseString.substring(x + "<Timestamp>".length(),y);
        // The time returned is in UNIX format so i need to multiply it by 1000 to use it
        Date d = new Date(Long.parseLong(timestamp) * 1000);
        Log.d("Response", d.toString() );
        return d.toString() ;
    } else{
        //Closes the connection.
        response.getEntity().getContent().close();
        throw new IOException(statusLine.getReasonPhrase());
    }
}catch (ClientProtocolException e) {
Log.d("Response", e.getMessage());
}catch (IOException e) {
Log.d("Response", e.getMessage());
}
return null;
}
Girish Nair avatar Oct 25 '2012 10:10 Girish Nair

Si no le importa la precisión de milisegundos y ya está usando Google Firebase o no le importa usarlo (proporcionan un nivel gratuito), consulte esto: https://firebase.google.com/docs/database /android/offline-capabilities#clock-skew

Básicamente, la base de datos de Firebase tiene un campo que proporciona un valor de compensación entre la hora del dispositivo y la hora del servidor de Firebase. Puede utilizar este desplazamiento para obtener la hora actual.

DatabaseReference offsetRef = FirebaseDatabase.getInstance().getReference(".info/serverTimeOffset");
offsetRef.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    double offset = snapshot.getValue(Double.class);
    double estimatedServerTimeMs = System.currentTimeMillis() + offset;
  }

  @Override
  public void onCancelled(DatabaseError error) {
    System.err.println("Listener was cancelled");
  }
});

Como dije, será inexacto según la latencia de la red.

rpattabi avatar Dec 14 '2016 10:12 rpattabi

Creo que la mejor solución es utilizar SNTP, en particular el código de cliente SNTP del propio Android, por ejemplo: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/ 4.1.1_r1/android/net/SntpClient.java/

Creo que Android usa SNTP para actualizaciones automáticas de fecha/hora cuando una red celular no está disponible (por ejemplo, tabletas wifi).

Creo que es mejor que las otras soluciones porque utiliza SNTP/NTP en lugar del protocolo de tiempo (RFC 868) utilizado por Apache TimeTCPClient. No sé nada malo sobre RFC 868, pero NTP es más nuevo y parece haberlo reemplazado y se usa más ampliamente. Creo que los dispositivos Android que no tienen celular usan NTP.

Además, porque utiliza enchufes. Algunas de las soluciones propuestas utilizan HTTP, por lo que perderán algo de precisión.

Tom avatar Jan 26 '2013 00:01 Tom