¿System.currentTimeMillis () devuelve la hora UTC?

93

Quiero obtener la hora UTC actual en milisegundos. Busqué en Google y obtuve algunas respuestas que System.currentTimeMillis () devuelve la hora UTC. pero no es así. Si hago lo siguiente:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

los tres tiempos son casi iguales (la diferencia está en milisegundos debido a las llamadas).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

y esta hora no es la hora UTC, sino que es la hora de mi zona horaria. ¿Cómo puedo obtener la hora UTC actual en Android?

g. revolución
fuente
4
Devuelve la hora actual del sistema en milisegundos desde el 1 de enero de 1970 a las 00:00:00 UTC
Blackbelt
3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt
3
El enlace anterior dice "Consulte la descripción de la clase Fecha para una discusión de las discrepancias leves que pueden surgir entre la" hora de la computadora "y la hora universal coordinada (UTC)". y en la documentación de java.util.Date encontrará: "Aunque la clase Date está destinada a reflejar la hora universal coordinada (UTC), es posible que no lo haga exactamente, dependiendo del entorno de host de la máquina virtual Java" -> por lo que puede Es posible que su máquina devuelva la hora no UTC
Marco Forberg
4
@ g.revolution: Es "el número de milisegundos desde el 1 de enero de 1970 a las 00:00:00 UTC". ¿Cómo esperaría que se ajustara a una zona horaria? Su zona horaria local no afecta la cantidad de milisegundos que han ocurrido desde esa época.
Jon Skeet

Respuestas:

132

Las tres líneas que ha mostrado le darán la cantidad de milisegundos desde la época de Unix, que es un punto fijo en el tiempo, no afectado por su zona horaria local.

Dices "esta hora no es la hora UTC". Sospecho que lo has diagnosticado incorrectamente. Sugeriría usar epochconverter.com para esto. Por ejemplo, en su ejemplo:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

No sabemos cuando generó ese valor, pero a menos que fuera realmente a las 8:01 am GMT, se trata de un problema con el reloj del sistema.

Ni System.currentTimeMillisel valor dentro de a Datesí mismo se ven afectados por la zona horaria. Sin embargo, debe tener en cuenta que Date.toString() usa la zona horaria local, lo que induce a error a muchos desarrolladores a pensar que una Dateestá intrínsecamente asociada con una zona horaria; no lo es, es solo un instante en el tiempo, sin una zona horaria asociada o incluso un sistema de calendario.

Jon Skeet
fuente
6
Entonces, básicamente, es decir que esta función devuelve el mismo valor si se llama al mismo tiempo desde diferentes zonas horarias, independientemente del reloj del host, ¿correcto?
Phillip
14
Hombre, esto me hace desear que el mundo adopte (podría) adoptar una única zona horaria. ¿A quién le importa si el número en el reloj es 00:00 o 08:00 cuando la gran cosa brillante aparece en el cielo? Las innumerables horas de tiempo productivo desperdiciado en esta reliquia histórica hacen que mi sangre hierva ...
corsiKa
En relación con esto, tenga en cuenta que la llamada subyacente a la función de reloj del sistema operativo tiene una "deriva" documentada de varios milisegundos. Java tiene un 'temporizador de alto rendimiento' si la intención es obtener una duración muy precisa de una operación (tiempo cuando una tarea comienza y termina, siendo el delta la cantidad de tiempo transcurrido). Ver: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague
@JonSkeet si toString () usa internamente la zona horaria, ¿cómo podría construir una cadena a partir de ella sin la zona horaria? En realidad, estoy generando un archivo en el servidor REST que tiene el nombre de archivo exactamente del valor de la hora de la medianoche ex "1551139200.json" (26 de febrero de 2019 12:00:00 a.m.) y al que se debe acceder desde la aplicación de Android una vez que el dispositivo System.currentTimeMillis () devuelve la hora exacta.
kiranking
@kiranking: Úselo Date.getTime()para encontrar el tiempo de milisegundos desde la época de Unix, divida por 1000 (ya que ese nombre de archivo está en segundos desde la época de Unix) y simplemente formatee ese número entero como una cadena.
Jon Skeet
3

Puedo confirmar que las tres llamadas podrían depender de la hora local, considerando la época, no el Date.toString()o cualquier método similar. Los he visto depender de la hora local en dispositivos específicos que ejecutan Android 2.3. No los he probado con otros dispositivos y versiones de Android. En este caso, la hora local se estableció manualmente.

La única forma confiable de obtener una hora UTC independiente es solicitando una actualización de ubicación utilizando GPS_PROVIDER. El getTime()valor de una ubicación recuperada NETWORK_PROVIDERtambién depende de la hora local. Otra opción es hacer ping a un servidor que devuelve una marca de tiempo UTC, por ejemplo.

Entonces, lo que hago es lo siguiente:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}
jlhonora
fuente
1
System.currentTimeMillis () devuelve un valor basado en UTC. En cuanto a la 'precisión' o exactitud del reloj del sistema operativo, aunque ciertamente esto afecta el resultado, no está relacionado de ninguna manera con el sistema o el valor de la zona horaria del entorno Java.
Darrell Teague
@DarrellTeague Insisto, vi valores diferentes en un dispositivo Huawei específico. Entonces no, no siempre devuelve la hora UTC correcta (descartando las diferencias de precisión)
jlhonora
La pregunta del OP era sobre el uso de una zona horaria de clase Java. No se trataba de hardware ni de la precisión del valor de tiempo devuelto. En pocas palabras, la JVM obtiene su tiempo del (abstracto) "reloj del sistema" operativo (que varía según el sistema operativo en términos de cómo funciona). Ver también: drdobbs.com/embedded-systems/… e implementaciones de "C" en sistemas operativos chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague