web-dev-qa-db-fra.com

Un moyen facile de convertir Java 8 LocalDateTime de Java en LocalDateTime de Joda

Existe-t-il un moyen facile de convertir Java 8 LocalDateTime en Joda's LocalDateTime?

L'une des façons consiste à le convertir en chaîne, puis à créer LocalDateTime de Joda à partir de cette chaîne.

17
Naresh

Convertir par Epoch millis (essentiellement une Java.util.Date()):

Java.time.LocalDateTime Java8LocalDateTime = Java.time.LocalDateTime.now();

// Separate steps, showing intermediate types
Java.time.ZonedDateTime Java8ZonedDateTime = Java8LocalDateTime.atZone(ZoneId.systemDefault());
Java.time.Instant Java8Instant = Java8ZonedDateTime.toInstant();
long millis = Java8Instant.toEpochMilli();
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis);

// Chained
org.joda.time.LocalDateTime jodaLocalDateTime =
        new org.joda.time.LocalDateTime(
            Java8LocalDateTime.atZone(ZoneId.systemDefault())
                              .toInstant()
                              .toEpochMilli()
        );

// One-liner
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(Java8LocalDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

Une seule ligne, mais longue, donc "facile"? Tout est relatif.

19
Andreas

Les deux types localDate se composent de (year, month, date), il suffit donc de copier ces valeurs:

public static org.joda.time.LocalDate toJoda(Java.time.LocalDate input) {
    return new org.joda.time.LocalDate(input.getYear(),
                                       input.getMonthValue(),
                                       input.getDayOfMonth());
}
5
araqnid

ne méthode légèrement plus courte:
Si vous pouvez vous en sortir en utilisant un ZoneOffset au lieu d'un ZoneId alors le code peut être légèrement raccourci.

Java.time.LocalDateTime Java8LDT = Java.time.LocalDateTime.now();
org.joda.time.LocalDateTime jodaLDT = new org.joda.time.LocalDateTime(
    Java8LDT.toInstant(ZoneOffset.UTC).toEpochMilli()
);

L'appel à la méthode atZone() peut être supprimé en fournissant le décalage de fuseau horaire à la méthode toInstant().

Explication plus détaillée
Juste pour clarifier, l'étape que j'ai supprimée consiste à créer l'objet ZonedDateTime intermédiaire. Cette partie de la séquence est toujours avec l'API Java 8 avant tout ce qui concerne Joda.

Le processus de conversion consiste d'abord à convertir le Java 8 LocalDateTime en nombre de millis depuis l'époque. Cela peut être réalisé de deux manières différentes. Par exemple dans la réponse d'Andreas:

LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Instant instant = zdt.toInstant();
long millis = instant.toEpochMilli();

Ou mon alternative:

LocalDateTime ldt = LocalDateTime.now();
Instant instant = ldt.toInstant(ZoneOffset.UTC);
long millis = instant.toEpochMilli();

La différence est que je saute la création d'un Java 8 ZonedDateTime et passe à la place le décalage de fuseau horaire à la méthode toInstant().

A partir de là, les deux réponses sont identiques.

org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis);

Avertissements
Cela fonctionne bien lors de la conversion à l'aide d'un décalage cohérent où aucune modification de l'heure d'été ne s'applique. Par exemple, UTC est toujours +0: 00. Si vous avez besoin de convertir en un fuseau horaire local où le décalage peut changer, vous aurez besoin de la réponse légèrement plus longue en utilisant atZone()

Un LocalDateTime avec les deux API (Java 8 et Joda) est un DateTime sans fuseau horaire. Cependant, si vous avez le nombre de millis depuis l'époque, vous avez besoin d'un décalage pour dériver une date et une heure. L'API Java 8 nécessite la transmission explicite d'un décalage ou d'un fuseau horaire, tandis que l'API Joda utilisera la valeur par défaut du système si aucune n'est transmise.

Une façon plus précise de construire le Joda LocalDateTime serait:

org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis, DateTimeZone.UTC);

Cela utilisera uniquement le fuseau horaire pendant la construction pour obtenir la date et l'heure correctes. Une fois que le constructeur a terminé le fuseau horaire ne fera pas partie de l'objet car LocalDateTime n'a pas de fuseau horaire.

1
Ben Thurley