java timezone ¿Por qué restar estas dos veces (en 1927) da un resultado extraño?




4 Answers

Has encontrado una discontinuidad de hora local :

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

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

timezone java example

Si ejecuto el siguiente programa, que analiza dos cadenas de fecha que hacen referencia a intervalos de 1 segundo y las 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-ld3 no es 1 (como lo esperaría de la diferencia de un segundo en los tiempos), sino 353 ?

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

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

Entonces ld4-ld3 será 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



Al incrementar el tiempo, debe volver a convertir a UTC y luego sumar o restar. Use la hora local solo para mostrar.

De esta manera, podrá caminar a través de los períodos donde las horas o los minutos pasan dos veces.

Si convirtió a UTC, agregue cada segundo y conviértalo a la hora local para su visualización. Irías a las 11:54:08 pm LMT - 11:59:59 pm LMT y luego a las 11:54:08 pm CST - 11:59:59 pm CST.




Lamento decir eso, 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 los tiempos no UTC a toda costa, excepto, tal vez, para la visualización.




En mi opinión, la localización generalizada e implícita en Java es su principal defecto de diseño. Puede estar destinado a interfaces de usuario, pero francamente, que realmente utiliza Java para las interfaces de usuario hoy en día, excepto en algunos IDE donde básicamente puede ignorar la localización porque los programadores no son exactamente el público objetivo. Puedes arreglarlo (especialmente en servidores Linux) por:

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

A los miembros del Proceso de la Comunidad Java les recomiendo:

  • Los métodos localizados no son los predeterminados, pero requieren que el usuario solicite explícitamente la localización.
  • en su lugar, use UTF-8 / UTC como el valor predeterminado FIJADO 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, ¿no son las variables estáticas globales un patrón anti-OO? Nada más son los valores predeterminados generalizados dados por algunas variables de entorno rudimentarias .......






Related