Naresh
Naresh

Reputation: 643

Easy way to convert Java 8's LocalDateTime to Joda's LocalDateTime

Is there any easy way to convert Java 8's LocalDateTime to Joda's LocalDateTime?

One of the ways is to convert it to String and then create Joda's LocalDateTime from that String.

Upvotes: 27

Views: 42511

Answers (3)

Ben Thurley
Ben Thurley

Reputation: 7141

A slightly shorter method:
If you can get away with using a ZoneOffset instead of a ZoneId then the code may be shortened slightly.

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

The call to the atZone() method can be dropped by providing the timezone offset to the toInstant() method.

More detailed explanation
Just to clarify, the step I have removed is with creating the intermediate ZonedDateTime object. This part of the sequence is still with the Java 8 API before anything to do with Joda.

The process of conversion first involves converting the Java 8 LocalDateTime to the number of millis since the epoch. This can be achieved in a couple of different ways. For example in Andreas' answer:

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

Or my alternative:

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

The difference is that I am skipping creating a Java 8 ZonedDateTime and instead passing the timezone offset to the toInstant() method.

From this point on the two answers are the same.

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

Caveats
This works well when converting using a consistent offset where no daylight savings changes apply. For example UTC is always +0:00. If you need to convert to a local timezone where the offset can change then you'll need the slightly longer answer using atZone()

A LocalDateTime with both API's (Java 8 and Joda) is a DateTime without a timezone. However, if you have the number of millis since the epoch then you need an offset to derive a date and time. The Java 8 API requires either an offset or timezone to be explicitly passed in, whereas the Joda API will use the system default if none is passed.

A more precise way to construct the Joda LocalDateTime would be:

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

This will only use the timezone during construction to get the correct date and time. Once the constructor has completed the timezone will not form part of the object since LocalDateTime has no timezone.

Upvotes: 0

araqnid
araqnid

Reputation: 133402

Both localDate types consist of (year, month, date), so just copy those values:

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

Upvotes: 6

Andreas
Andreas

Reputation: 159086

Convert through epoch millis (essentially a 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());

Single line, but long, so "easy"? It's all relative.

Upvotes: 30

Related Questions