Precisión de System.currentTimeMillis(), new Date().getTime() y Calendar.getInstance().getTimeInMillis()?

Estaba a punto de usar System.currentTimeMillis() en Eclipse cuando noté que el siguiente párrafo aparece en su Javadoc:

Returns the current system time in milliseconds since January 1, 1970
00:00:00 UTC. This method shouldn't be used for measuring timeouts or
other elapsed time measurements, as changing the system time can affect
the results.

Entonces eso significa que no puedo confiar en System.currentTimeMillis() si quisiera mantener específicamente una referencia a este punto actual en el tiempo. ¿Cuál es la forma más precisa de hacerlo, entonces? ¿Los tres métodos marcan la hora actual de manera diferente entre sí?

ACTUALIZACIÓN: Lo que estoy tratando de hacer es medir la diferencia entre dos puntos en el tiempo en dos ejecuciones de programas separadas. Mi miedo es que si uso System.currentTimeMillis() y el usuario juega con la hora del sistema después de la primera ejecución, es posible que obtenga un valor extraño e inesperado durante la segunda.

preguntado el 28 de agosto de 12 a las 12:08

Supongo que puedes usarlo... siempre y cuando no cambies la hora del sistema. :) De todos modos, en Windows no será muy preciso. -

Relacionado: stackoverflow.com/questions/11591000/… Si necesita asegurarse de que los cambios de hora no afecten su medición: System.nanotime(). -

¿Solo quieres medir las diferencias horarias? ¿O realmente quieres una referencia a la hora actual? -

Voy a medir las diferencias de tiempo durante largos períodos dentro de un día. Sin embargo, ¿es eso diferente de la necesidad de hacer referencia a la hora actual? -

4 Respuestas

Deberías usar System.nanoTime(), de los documentos de la API:

Devuelve el valor actual del temporizador del sistema disponible más preciso, en nanosegundos.

Este metodo solo se puede usar para medir el tiempo transcurrido y no está relacionado con ninguna otra noción de sistema o tiempo de reloj de pared. El valor devuelto representa nanosegundos desde algún tiempo fijo pero arbitrario (quizás en el futuro, por lo que los valores pueden ser negativos). Este método proporciona una precisión de nanosegundos, pero no necesariamente una precisión de nanosegundos. No se garantiza la frecuencia con la que cambian los valores. Diferencias en llamadas sucesivas que abarcan más de aproximadamente 292 años (263 nanosegundos) no calculará con precisión el tiempo transcurrido debido al desbordamiento numérico.

Respondido 28 ago 12, 12:08

He editado para superíndice la potencia, de lo contrario obtienes 263 nanosegundos, que es bastante menos que 292 años... - Rico

Pero, ¿no es esto simplemente lo mismo que currentTimeInMillis(), solo precisa hasta el nivel de nanosegundos, pero aún se puede hacer que se comporte mal si se cambió la hora del sistema en el dispositivo o la computadora? - MLQ

@mattquiros no, "... no relacionado con ninguna otra noción de sistema o tiempo de reloj de pared". - Dacwe

@mattquiros Tenga en cuenta también que no lo es "preciso hasta el nivel de nanosegundos" aunque el nombre lo sugiera. Como se señaló en la respuesta: "Este método proporciona una precisión de nanosegundos, pero no necesariamente una precisión de nanosegundos. No se garantiza la frecuencia con la que cambian los valores". - Assylias

Ah, okey. Lo estaba pensando dos veces debido a la parte del "valor actual del temporizador del sistema disponible más preciso" (primera oración). - MLQ

Si desea referirse a un punto específico en el tiempo, definitivamente puede confiar en System.currentTimeInMillis(). Los tres métodos que describe marcarán el tiempo de la misma manera, la diferencia es solo en qué tipo de objeto está envuelto. Use la variante que necesita en su programa.

Si desea medir la diferencia entre dos puntos en el tiempo durante la ejecución de un programa, utilice System.nanoTime() preferiblemente.

Para obtener la diferencia de tiempo entre dos puntos en el tiempo en dos ejecuciones de programas separadas, deberá confiar en fuentes de tiempo externas si tiene miedo de que el usuario pueda jugar con el reloj del sistema. Por ejemplo, puedes echar un vistazo a Java SNTP Client.

Respondido 28 ago 12, 12:08

¿Qué pasa si quiero medir la diferencia entre dos puntos en el tiempo en dos ejecuciones de programa separadas? Según tengo entendido, si uso System.currentTimeInMillis(), mi usuario de alguna manera puede jugar con la hora del sistema y podría obtener un valor inesperado en la segunda ejecución. - MLQ

use System.nanoTime() que System.currentTimeInMillis()

Respondido 28 ago 12, 12:08

Una característica de System.currentTimeMillis() es que se corrige periódicamente para que sea más preciso a la larga. Esto puede significar que el tiempo retrocede o salta hacia adelante cuando se corrige.

Una característica de System.nanoTime() es que es monótonamente creciente. No se garantiza que esté relacionado entre las JVM, pero en muchos sistemas es aproximadamente el tiempo transcurrido desde el último reinicio del procesador. es decir, se restablecerá en un reinicio.

Respondido 28 ago 12, 13:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.