¿Por qué restar estos dos tiempos (en 1927) da un resultado extraño?

7031
Freewind 2011-07-27 22:15.

Si ejecuto el siguiente programa, que analiza dos cadenas de fechas que hacen referencia a tiempos de 1 segundo de diferencia y los compara:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

La salida es:

353

¿Por qué ld4-ld3no 1(como esperaría de la diferencia de un segundo en los tiempos), pero 353?

Si cambio las fechas a las horas 1 segundo después:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";  

Entonces ld4-ld3será 1.


Versión de Java:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)
Timezone(`TimeZone.getDefault()`):

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]

Locale(Locale.getDefault()): zh_CN

10 answers

11177
Jon Skeet 2011-07-27 22:31.

Es un cambio de zona horaria el 31 de diciembre en Shanghai.

Consulte esta página para obtener detalles de 1927 en Shanghai. Básicamente, a la medianoche de finales de 1927, los relojes retrocedieron 5 minutos y 52 segundos. Entonces, "1927-12-31 23:54:08" en realidad sucedió dos veces, y parece que Java lo está analizando como el último instante posible para esa fecha / hora local, de ahí la diferencia.

Solo otro episodio en el mundo a menudo extraño y maravilloso de las zonas horarias.

EDITAR: ¡ Deja de presionar! Cambios en el historial ...

La pregunta original ya no demostraría el mismo comportamiento, si se reconstruyera con la versión 2013a de TZDB . En 2013a, el resultado sería 358 segundos, con un tiempo de transición de 23:54:03 en lugar de 23:54:08.

Solo me di cuenta de esto porque estoy recopilando preguntas como esta en Noda Time, en forma de pruebas unitarias ... La prueba ahora se ha cambiado, pero simplemente muestra que ni siquiera los datos históricos son seguros.

EDITAR: La historia ha cambiado de nuevo ...

En TZDB 2014f, el tiempo del cambio se ha movido a 1900-12-31, y ahora es un cambio de solo 343 segundos (por lo que el tiempo entre ty t+1es 344 segundos, si ve lo que quiero decir).

EDITAR: Para responder una pregunta sobre una transición en 1900 ... parece que la implementación de la zona horaria de Java trata todas las zonas horarias simplemente como si estuvieran en su hora estándar para cualquier instante antes del inicio de las 1900 UTC:

import java.util.TimeZone;

public class Test {
    public static void main(String[] args) throws Exception {
        long startOf1900Utc = -2208988800000L;
        for (String id : TimeZone.getAvailableIDs()) {
            TimeZone zone = TimeZone.getTimeZone(id);
            if (zone.getRawOffset() != zone.getOffset(startOf1900Utc - 1)) {
                System.out.println(id);
            }
        }
    }
}

El código anterior no produce salida en mi máquina con Windows. Por lo tanto, cualquier zona horaria que tenga un desplazamiento diferente al estándar a principios de 1900 lo contará como una transición. La propia TZDB tiene algunos datos que se remontan a antes, y no se basa en ninguna idea de un tiempo estándar "fijo" (que es lo que se getRawOffsetsupone que es un concepto válido), por lo que otras bibliotecas no necesitan introducir esta transición artificial.

1644
Michael Borgwardt 2011-07-27 22:38.

Ha encontrado una discontinuidad de la hora local :

Cuando la hora estándar local estaba a punto de llegar al domingo 1 de enero de 1928, los relojes de las 00:00:00 se retrasaron 0:05:52 horas al sábado 31 de diciembre de 1927, 23:54:08 hora estándar local.

Esto no es particularmente extraño y ha sucedido en casi todas partes en un momento u otro, ya que las zonas horarias se cambiaron o cambiaron debido a acciones políticas o administrativas.

688
Raedwald 2011-07-29 01:50.

La moraleja de esta extrañeza es:

  • Utilice fechas y horas en UTC siempre que sea posible.
  • Si no puede mostrar una fecha u hora en UTC, indique siempre la zona horaria.
  • Si no puede solicitar una fecha / hora de entrada en UTC, solicite una zona horaria indicada explícitamente.
379
PatrickO 2011-07-31 06:55.

Al incrementar el tiempo, debe volver a convertir a UTC y luego sumar o restar. Utilice la hora local solo para la visualización.

De esta manera, podrá recorrer los períodos en los que las horas o los minutos suceden dos veces.

Si convirtió a UTC, agregue cada segundo y conviértalo a la hora local para mostrarlo. Pasaría por 11:54:08 pm LMT - 11:59:59 pm LMT y luego 11:54:08 pm CST - 11:59:59 pm CST.

320
Rajshri 2012-05-16 19:31.

En lugar de convertir cada fecha, puede utilizar el siguiente código:

long difference = (sDt4.getTime() - sDt3.getTime()) / 1000;
System.out.println(difference);

Y luego mira que el resultado es:

1
236
user1050755 2014-02-18 12:44.

Lamento decirlo, pero la discontinuidad del tiempo se ha movido un poco en

JDK 6 hace dos años, y en JDK 7 recientemente en la actualización 25 .

Lección para aprender: evite las horas que no sean UTC a toda costa, excepto quizás para la visualización.

208
Daniel C. Sobral 2014-01-04 04:43.

Como explicaron otros, hay una discontinuidad de tiempo allí. Hay dos posibles desplazamientos de zona horaria para 1927-12-31 23:54:08at Asia/Shanghai, pero solo un desplazamiento para 1927-12-31 23:54:07. Entonces, dependiendo de qué compensación se use, hay una diferencia de un segundo o una diferencia de 5 minutos y 53 segundos.

Este ligero cambio de compensaciones, en lugar del horario de verano habitual al que estamos acostumbrados, oscurece un poco el problema.

Tenga en cuenta que la actualización de 2013a de la base de datos de la zona horaria movió esta discontinuidad unos segundos antes, pero el efecto aún sería observable.

El nuevo java.timepaquete en Java 8 permite que el usuario vea esto con mayor claridad y proporciona herramientas para manejarlo. Dado:

DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.append(DateTimeFormatter.ISO_LOCAL_DATE);
dtfb.appendLiteral(' ');
dtfb.append(DateTimeFormatter.ISO_LOCAL_TIME);
DateTimeFormatter dtf = dtfb.toFormatter();
ZoneId shanghai = ZoneId.of("Asia/Shanghai");

String str3 = "1927-12-31 23:54:07";  
String str4 = "1927-12-31 23:54:08";  

ZonedDateTime zdt3 = LocalDateTime.parse(str3, dtf).atZone(shanghai);
ZonedDateTime zdt4 = LocalDateTime.parse(str4, dtf).atZone(shanghai);

Duration durationAtEarlierOffset = Duration.between(zdt3.withEarlierOffsetAtOverlap(), zdt4.withEarlierOffsetAtOverlap());

Duration durationAtLaterOffset = Duration.between(zdt3.withLaterOffsetAtOverlap(), zdt4.withLaterOffsetAtOverlap());

Luego durationAtEarlierOffsetserá un segundo, mientras durationAtLaterOffsetque serán cinco minutos y 53 segundos.

Además, estas dos compensaciones son las mismas:

// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();

Pero estos dos son diferentes:

// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();

// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();

Se puede ver el mismo problema comparando 1927-12-31 23:59:59con 1928-01-01 00:00:00, sin embargo, en este caso, es la compensación temprana que produce la divergencia más tiempo, y es la fecha más temprana que tiene dos posibles desplazamientos.

Otra forma de abordar esto es comprobar si se está produciendo una transición. Podemos hacer esto así:

// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);

// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);

Puede verificar si la transición es una superposición donde hay más de un desplazamiento válido para esa fecha / hora o un intervalo donde esa fecha / hora no es válida para esa identificación de zona, utilizando los métodos isOverlap()y isGap()en zot4.

Espero que esto ayude a las personas a manejar este tipo de problemas una vez que Java 8 esté ampliamente disponible, o para aquellos que usan Java 7 y adoptan el backport JSR 310.

173
user1050755 2014-11-27 05:58.

IMHOla localización omnipresente e implícita en Java es su mayor defecto de diseño. Puede estar destinado a interfaces de usuario, pero, francamente, quién realmente usa Java para interfaces de usuario hoy, excepto para algunos IDE en los que básicamente puede ignorar la localización porque los programadores no son exactamente el público objetivo para él. Puede solucionarlo (especialmente en servidores Linux) de la siguiente manera:

  • exportar LC_ALL=C TZ=UTC
  • configure el reloj de su sistema en UTC
  • nunca use implementaciones localizadas a menos que sea absolutamente necesario (es decir, solo para visualización)

A los miembros de Java Community Process les recomiendo:

  • hacen métodos localizados, no los predeterminados, pero requieren que el usuario solicite explícitamente la localización.
  • use UTF-8/UTCcomo el valor predeterminado FIJO en su lugar porque ese es simplemente el valor predeterminado hoy. No hay razón para hacer otra cosa, excepto si desea producir hilos como este.

Quiero decir, vamos, ¿las variables estáticas globales no son un patrón anti-OO? Nada más son esos omnipresentes valores predeterminados dados por algunas variables de entorno rudimentarias .......

25
zixuan 2019-02-11 11:47.

Como dijeron otros, es un cambio de hora en 1927 en Shanghai.

Fue 23:54:07en Shanghái, en la hora estándar local, pero luego de 5 minutos y 52 segundos, pasó al día siguiente a las 00:00:00, y luego la hora estándar local volvió a cambiar a 23:54:08. Entonces, es por eso que la diferencia entre los dos tiempos es de 343 segundos, no de 1 segundo, como hubiera esperado.

El tiempo también puede estropearse en otros lugares como Estados Unidos. Estados Unidos tiene el horario de verano. Cuando comienza el horario de verano, el tiempo avanza 1 hora. Pero después de un tiempo, el horario de verano finaliza y retrocede 1 hora hasta la zona horaria estándar. Entonces, a veces, al comparar tiempos en los EE. UU., La diferencia es de 3600segundos, no de 1 segundo.

Pero hay algo diferente en estos cambios de dos tiempos. El último cambia continuamente y el primero fue solo un cambio. No volvió a cambiar ni volvió a cambiar en la misma cantidad.

Es mejor usar UTC a menos que sea necesario usar una hora que no sea UTC como en la pantalla.

5
Neeraj Bansal 2020-07-07 04:10.

Esto sucede porque esas son las reglas de zona horaria para el año 31 de diciembre de 1927 en Shanghai. Si va a esta página y elige "Cambios de zona horaria de 1900 a 1924", verá que en 1900 la fecha y la hora son "UTC +8: 05: 43 horas durante todo el período".

Entonces, Java solo muestra la hora configurada para esa zona horaria, en ese año.

Si cambia su zona horaria predeterminada a Hong Kong, se mostrarán los resultados correctos.

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Hong_Kong"));

Tenga en cuenta que la zona horaria cambió de CST (hora estándar de China, el "equivalente de 3 letras" a Asia / Shanghai) a HKT (el nombre de 3 letras de la zona horaria de Hong Kong).

Pero cambiar la zona horaria no es una buena solución. Por lo tanto, utilice la hora UTC del sistema siempre que sea posible. Siempre dará la hora local después de la conversión.

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Se revela la estatua de Godzilla más nueva de Tokio

Se revela la estatua de Godzilla más nueva de Tokio

Anteriormente, Kotaku informó que un hotel Godzilla se estaba abriendo en Tokio este abril. Junto al hotel, estaba programada la aparición de una enorme cabeza de 'Zilla, pero todo lo que hemos visto fueron imágenes conceptuales computarizadas.

El alcalde de Chicago realmente quiere que Elon Musk perfore un túnel debajo de la ciudad

El alcalde de Chicago realmente quiere que Elon Musk perfore un túnel debajo de la ciudad

Foto: Getty Desde que lanzó The Boring Company hace un año, Elon Musk ha mencionado varios sitios de construcción posibles para el negocio de perforación de túneles y ha descartado una vaga referencia a una aprobación gubernamental "verbal" para un túnel Hyperloop que conecta la ciudad de Nueva York y Washington. , CC. Pero ahora sabemos que al menos un alcalde quiere que Musk perfore un agujero debajo de su ciudad.

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Cuéntanos tus mejores trucos de Washington, DC

Cuéntanos tus mejores trucos de Washington, DC

Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language