2016-09-27 5 views
2

Les travaux suivants, mais il semble un peu maladroit de convertir le temps à un long, puis un Instant ainsi que la conversion du fuseau horaire à un TimeZone, puis un ZoneId. Y a-t-il une façon plus propre de faire cela?Quelle est la meilleure façon de convertir un org.joda.time.DateTime en un java.time.OffsetDateTime?

java.time.Instant instant = java.time.Instant.ofEpochMilli(jodaDateTime.getMillis()); 
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, 
     jodaDateTime.getZone().toTimeZone().toZoneId()); 
+4

Cela semble être la complexité attendue de la solution –

+2

Il semble bien - si les performances ne sont pas une préoccupation, vous pouvez le faire via des chaînes:. 'OffsetDateTime.parse (ISODateTimeFormat.dateTime() FMT (jodaDateTime), DateTimeFormatter.ISO_OFFSET_DATE_TIME) - Pas sûr que ce soit moins maladroit ... – assylias

+1

Je vous suggère d'utiliser l'un ou l'autre dans votre code. En utilisant à la fois joda.time et java-time, vous pouvez entrer dans des complications et des confusions dans votre code. L'autre solution que vous pouvez faire est d'utiliser un formateur pour sortir votre temps de joda à string, puis le désérialiser en utilisant un JavaTime Formatter différent. –

Répondre

0

Cela semble être la manière générale de faire une telle conversion.

Comme, le facteur commun entre eux semble être le longepochMilli valeur les classes des deux API de ne sont pas interopérables entre eux (DateTimeFormatter et ainsi de suite de vous ne pouvez pas utiliser DateTime de Joda avec Java Time).

Donc, je ne vois pas de meilleure façon que de créer un java.time.Instant, puis de le convertir en OffsetDateTime en utilisant le fuseau horaire de l'objet de Joda.

Eh bien, je pense qu'il y a une chose qui peut être légèrement améliorée. Ce code:

jodaDateTime.getZone().toTimeZone().toZoneId() 

La méthode toTimeZone() crée une instance java.util.Timezone, qui est utilisé pour créer une java.time.ZoneId via la méthode toZoneId().

Vous pouvez éviter la création de cet objet TimeZone temporaire en faisant:

ZoneId.of(jodaDateTime.getZone().getID()) 

Ce code ne crée pas l'objet TimeZone temporaire, et crée directement le ZoneId. Comme DateTimeZone doesn't work with short IDs de Joda (comme IST ou), nous pouvons supposer que l'ID sera reconnaissable par la classe ZoneId (car il fonctionne également avec les noms d'ID longs, tels que Europe/London). Cela fonctionne également si l'ID DateTimeZone de Joda est un décalage (tel que +01:00).

Vous ne savez pas si éviter la création d'un objet temporaire est assez propre, mais de toute façon c'est une amélioration (minuscule, mais elle l'est toujours).

Ainsi, le code final sera très semblable à la vôtre, avec seulement le changement proposé ci-dessus:

// java.time.Instant 
Instant instant = Instant.ofEpochMilli(jodaDateTime.getMillis()); 

// create the OffsetDateTime 
OffsetDateTime.ofInstant(instant, ZoneId.of(jodaDateTime.getZone().getID())); 

Il y a une autre alternative (très similaire, mais pas sûr si propre): obtenir le total offset (au lieu du fuseau horaire) et l'utiliser pour créer un java.time.ZoneOffset:

long millis = jodaDateTime.getMillis(); 
// java.time.Instant 
Instant instant = Instant.ofEpochMilli(millis); 

// get total offset (joda returns milliseconds, java.time takes seconds) 
int offsetSeconds = jodaDateTime.getZone().getOffset(millis)/1000; 
OffsetDateTime.ofInstant(instant, ZoneOffset.ofTotalSeconds(offsetSeconds)); 

Vous pouvez également u se la suggestion faite par @assylias' comment, mais je ne suis pas sûr si le formatage à un String, puis l'analyse à OffsetDateTime est plus propre que cela (bien que cela fonctionne aussi).