Cómo configurar manualmente el horario de verano (DST) Fecha de cambio en Java

Evandro Pomatti:

Mi país cambió la fecha del cambio de horario de verano a partir "21 de Octubre" a "4 de noviembre" y tenemos que aplicar esta en nuestro back-end.

La solución apropiada es para actualizar la configuración del sistema operativo, pero tenemos restricciones para hacerlo (dependencias de legado). Estamos en busca de una solución.

¿Es posible usar el código y cambiar la fecha de cambio de horario de verano mediante programación?

GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(0);
gc.set(2018, Calendar.OCTOBER, 21, 0, 0, 0);
gc.setTimeZone(TimeZone.getTimeZone("Brazil/East"));
XMLGregorianCalendar xml = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
System.out.println("XML Date: " + xml.toString());

Salida debe ser -03:00:

XML Date: 2018-10-21T01:00:00.000-02:00
Albahaca Bourque:

irrelevante OS

La configuración del sistema operativo es irrelevante. La mayoría de las implementaciones de Java por defecto recoger su zona inicial de tiempo por defecto del sistema operativo huésped tras su lanzamiento. Sin embargo, la definición de las zonas de tiempo se almacena dentro de la aplicación Java.

Java tiempo de actualización de zona

Así que hay que actualizar las definiciones de zona horaria dentro de su aplicación Java. La mayoría de las implementaciones utilizan la base de datos tz también conocido como tzdata .

Para la implementación de Java de marca-Oracle, Oracle proporciona la herramienta de actualización de zona horaria . Esa página de destino tiene una como de la fecha de 2018-08, lo que tal vez se han incluido cambios de su zona horaria. Pero sugiero que investigar más de cerca para verificar.

Para otras implementaciones, consulte con el vendedor. Es posible que hayan proporcionado una versión actualizada de la JVM para incluir el tzdata fresco. O tal vez ellos también proporcionan una herramienta de actualización. O tal vez usted puede reemplazar el archivo tzdata manualmente.

Evitar la zona mangling con código

Le recomiendo encarecidamente que evitar tratar de hacer ajustes artificiales para el mismo desplazamiento en el código. Es probable que se equivocan. El trabajo a tiempo en la fecha sorprendentemente complicado y confuso.

Pero si insiste, en primer lugar, evitar los legados de edad clases de fecha y hora terribles como GregorianCalendary Calendary Date. Estos fueron reemplazados hace años por JSR 310. Si debe interoperar con código antiguo aún no se actualizó a java.time , hacer su trabajo en las clases modernas y luego en el convertido final a través de nuevos métodos añadidos a las antiguas clases.

Utilizar los modernos la java.time clases, a saber:

  • Instant (Por un momento en UTC)
  • OffsetDateTime (Por un momento con un desplazamiento-de-UTC de horas-minutos-segundos, pero sin zona horaria)
  • ZonedDateTime (Por un momento en una zona de tiempo particular)

Puede buscar desbordamiento de pila durante muchos ejemplos y explicaciones que utilizan estas clases existentes. Usted debe centrarse en OffsetDateTime, ZoneOffset(en lugar de ZoneId), y Instantpuesto que usted debe evitar ZonedDateTimesi su know su tzdata archivo a ser obsoletos.

Mismo momento, el tiempo del reloj de pared diferente

introducir descripción de la imagen aquí

OffsetDateTime::withOffsetSameInstant​

OffsetDateTime odt = OffsetDateTime.parse( "2018-10-21T01:00:00.000-02:00" ) ;
ZoneOffset offset = ZoneOffset.ofHours( -3 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant​( offset ) ;  // Same moment, same point on the timeline, different wall-clock time.

odt.toString (): 2018-10-21T01: 00-02: 00

odt2.toString (): 2018-10-21T00: 00-03: 00

En ese ejemplo, tanto odty odt2representan el mismo momento simultánea, el mismo punto en la línea de tiempo. Si extrae una Instant(un valor en UTC), los resultados serán los mismos momentos. Sólo el tiempo del reloj de pared es diferente.

Instant instant1 = odt.toInstant() ;  // Adjust to UTC.
Instant instant2 = odt2.toInstant() ;
boolean sameMoment = instant1.equals( instant2 ) ; 

instant1.toString (): 2018-10-21T03: 00: 00Z

instant2.toString (): 2018-10-21T03: 00: 00Z

sameMoment = true

El Zsobre los medios finales UTC, un UTC offset-de-de cero, +00:00. El Zse pronuncia “Zulu”. Definido por la ISO 8601 estándar.

Diferente momento, el tiempo mismo reloj de pared

introducir descripción de la imagen aquí

OffsetDateTime::withOffsetSameLocal​

In contrast, you may want to force the time-of-day thereby representing a different moment. For that, use withOffsetSameLocal method. Be very aware that you are changing the meaning of data, you are moving to another point on the timeline.

OffsetDateTime differentMomentButSameTimeOfDay = odt. withOffsetSameLocal( offset ) ;

differentMomentButSameTimeOfDay.toString(): 2018-10-21T01:00-03:00

Extract the instant to see we have a different moment.

Instant differentInstant = differentMomentButSameTimeOfDay.toInstant() ;

differentInstant.toString(): 2018-10-21T04:00:00Z

Notice the 4 AM UTC versus 3 AM UTC seen above. This moment here occurs an hour after the moment above. Two different points on the timeline.

Do not attempt this work until you fully comprehend the concept of points on the timeline, and changing between points being entirely different than adjusting offsets. Practice extensively before doing real work. Half-hearted guessing will land you in a world of hurt and headache.

And, as I suggested above, your time would be much better spent installing updated tzdata files rather than hacking these offsets.

Live code

See all the code above run live at IdeOne.com.

Update tzdata everywhere

For best results, you should be updating the tzdata (or equivalent) in all these various places:

  • Your operating systems
  • Your JVMs
  • Your database engines, such as Postgres
  • Any libraries bundling their own time zone info (ex: Joda-Time)

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

El ThreeTen-Extra proyecto se extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles futuras adiciones a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=173780&siteId=1
Recomendado
Clasificación