¿Determinar las fechas del cambio de horario de verano (tanto hacia adelante como hacia atrás) para una zona horaria en Java?

I realize that you can check if a Date is inDaylightTime, but how can I determine when (or if) that Date switches to and from DST? I can iterate over every day and check if it's inDaylightTime, but is there a cleaner solution/method?

preguntado el 08 de noviembre de 11 a las 16:11

2 Respuestas

Sugeriría usar Hora de Joda - su DateTimeZone la clase tiene nextTransition y previousTransition métodos.

Note that transitions can occur for reasons other than DST - a change in standard time, or perhaps a change in the name of the zone interval. But that's how you'd find out, anyway :)

(Joda Time is a much better date and time library to start with, to be honest.)

respondido 08 nov., 11:20

+1 and I would love to use a different library, but I should have mentioned I'm working with legacy code and have to use the Java Date and DateTime :-\ - Igor

@GrailsDev: Even if you're not going to use Joda Time elsewhere, can you not introduce it even for this bit? (I can't see anything which will give you transitions in the Java standard classes, even for SimpleTimeZone.) - Jon Skeet

I suppose I can... was wondering more if it's possible in the default Java class. - Igor

@GrailsDev: Not that I can see. Joda Time makes it pretty easy to convert from a Java Date though. Maybe you can introduce it throughout the project by stealth ;) - Jon Skeet

Any way to do it without using Joda ? in Java version less than 8. - DevilCode

java.time

La java.util API de fecha y hora y su API de formato, SimpleDateFormat están desactualizados y son propensos a errores. Se recomienda dejar de usarlos por completo y cambiar al API de fecha y hora moderna*.

Además, a continuación se cita un aviso del página de inicio de Joda-Time:

Tenga en cuenta que desde Java SE 8 en adelante, se solicita a los usuarios que migren a java.time (JSR-310), una parte central del JDK que reemplaza este proyecto.

Solución usando java.time, la API de fecha y hora moderna: Utilizan ZoneRules#nextTransition y ZoneRules#previousTransition.

Demostración:

import java.time.Instant;
import java.time.ZoneId;
import java.time.zone.ZoneRules;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        ZoneRules zoneRules = ZoneId.of("Europe/London").getRules();

        System.out.println(zoneRules.nextTransition(now));

        System.out.println(zoneRules.previousTransition(now));
    }
}

Salida:

Transition[Overlap at 2021-10-31T02:00+01:00 to Z]
Transition[Gap at 2021-03-28T01:00Z to +01:00]

DEMO EN LINEA

You can understand the output from the siguientes imágenes:

enter image description here

From the image, you can see that on 28 Mar 2021, after 00:59, the time changed to 02:00 i.e. there was no 01:00 that night. Is there a way to know the local time and the zone offset just before the transition happened? Check ZoneOffsetTransition or the following demo for the answer.

What were the local time and the zone offset before the transition?

import java.time.Instant;
import java.time.ZoneId;
import java.time.zone.ZoneOffsetTransition;

public class Main {
    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("Europe/London");
        ZoneOffsetTransition nextTransition = zoneId.getRules().previousTransition(Instant.now());
        System.out.println("Local date-time before the transition: " + nextTransition.getDateTimeBefore());
        System.out.println("Zone offset before the transition: " + nextTransition.getOffsetBefore());
    }
}

Salida:

Local date-time before the transition: 2021-03-28T01:00
Zone offset before the transition: Z

DEMO EN LINEA

Obtenga más información sobre la API de fecha y hora moderna en Sendero: fecha y hora.


* Por cualquier motivo, si tiene que ceñirse a Java 6 o Java 7, puede utilizar ThreeTen-Backport que soporta la mayor parte de java.time funcionalidad a Java 6 y 7. Si está trabajando para un proyecto de Android y su nivel de API de Android aún no es compatible con Java-8, marque API de Java 8+ disponibles mediante desugaring y Cómo utilizar ThreeTenABP en un proyecto de Android.

Respondido 17 Jul 21, 19:07

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