Cómo obtener la hora actual desde internet en android

Estoy haciendo una aplicación en la que quiero obtener la hora actual de internet.

Sé cómo obtener el tiempo del dispositivo usando System.currentTimeMillis , e incluso después de buscar mucho, no obtuve ninguna pista sobre cómo obtenerlo de Internet.

Puede obtener tiempo de los servidores de hora de Internet utilizando el siguiente progtwig

 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ías la biblioteca Apache Commons Net para que esto funcione. Descargue la biblioteca y agregue a la ruta de comstackción de su proyecto.

(O también puede usar la biblioteca recortada de Apache Commons Net aquí: https://www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar . Esto es suficiente para obtener tiempo de Internet)

2. Ejecuta el progtwig. Obtendrá el tiempo impreso en su consola.

Este es un método que he creado para ti, puedes usar esto 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(""); int y = responseString.indexOf(""); //I am using the x + "" because x alone gives only the start value Log.d("Response", responseString.substring(x + "".length(),y) ); String timestamp = responseString.substring(x + "".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; } 

Deberá tener acceso a un servicio web que proporcione la hora actual en formato XML o JSON.

Si no encuentra ese tipo de servicio, puede analizar el tiempo desde una página web, como http://www.timeanddate.com/worldclock/ , o alojar su propio servicio horario en un servidor utilizando una página PHP simple para ejemplo.

Consulte JSoup para el análisis sintáctico de páginas HTML.

Creo que la mejor solución es usar SNTP, en particular el código de cliente SNTP de 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 las actualizaciones automáticas de fecha y hora cuando una red celular no está disponible (por ejemplo, tabletas wifi).

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

Además, porque usa sockets. Algunas de las soluciones propuestas usan HTTP por lo que perderán algo en su precisión.

Nada de lo anterior funcionó de mí. Esto es con lo que terminé (con Volley);
Este ejemplo también se convierte en otra zona horaria.

  Long time = null; RequestQueue queue = Volley.newRequestQueue(this); String url ="http://www.timeapi.org/utc/now"; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(String response) { try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = simpleDateFormat.parse(response); TimeZone tz = TimeZone.getTimeZone("Israel"); SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); destFormat.setTimeZone(tz); String result = destFormat.format(date); Log.d(TAG, "onResponse: " + result.toString()); } catch (ParseException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.w(TAG, "onErrorResponse: "+ error.getMessage()); } }); queue.add(stringRequest); return time; 

Volley de importación en gradle:

 compile 'com.android.volley:volley:1.0.0' 

Si no le importa la precisión en milisegundos, y si ya utiliza 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 usar 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á inexacta en función de la latencia de la red.