How to convert Joda Localdate to Joda DateTime?
I'm trying to simply add TimeZone information back into a LocalDate before performing some more calculations. The LocalDate came from using the ObjectLab LocalDateCalculator to add days to an existing DateTime but the method needs to return a modified ReadableInstant to form an Interval which I can then inspect.
The code I'm trying amounts to a conversion of Joda LocalDate to Joda DateTime:
LocalDate contextLocalBusinessDate = calculator.getCurrentBusinessDate();
DateTime businessDateAsInContextLocation = new DateTime(contextLocalBusinessDate, contextTimeZone);
The error I get is from Joda's conversion system:
java.lang.IllegalArgumentException: No instant converter found for type: org.joda.time.LocalDate
at org.joda.time.convert.ConverterManager.getInstantConverter(ConverterManager.java:165)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:147)
at org.开发者_Go百科joda.time.DateTime.<init>(DateTime.java:192)
I'm looking for a fix to this problem, or a workaround that results in an accurate Interval with full timezone information.
There are various methods on LocalDate
for this, including:
LocalDate::toDateTimeAtCurrentTime()
LocalDate::toDateTimeAtStartOfDay()
LocalDate::toDateTime( LocalTime )
LocalDate::toDateTime( LocalTime , DateTimeZone )
You have to be explicit about what you want the time component to be in the resulting DateTime
object, which is why DateTime
's general-conversion constructor can't do it.
java.time
Quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time
, the modern Date-Time API:
A common way to convert a LocalDate
to ZonedDateTime
is to first convert it to LocalDateTime
with 00:00
hours using LocalDate#atStartOfDay
and then combine with a ZoneId
. An alternative to LocalDate#atStartOfDay
is LocalDate#atTime(LocalTime.MIN)
.
Note that LocalDate#atStartOfDay(ZoneId)
is another variant of atStartOfDay
. However, it may not return a ZonedDateTime
with 00:00
hours on the day of DST transition.
You can convert from ZonedDateTime
to OffsetDateTime
using ZonedDateTime#toOffsetDateTime
.
Demo:
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
// Note: Change the ZoneId as applicable e.g. ZoneId.of("Europe/London")
ZonedDateTime zdt = today.atStartOfDay().atZone(ZoneId.systemDefault());
System.out.println(zdt);
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
}
}
Output:
2021-07-11T00:00+01:00[Europe/London]
2021-07-11T00:00+01:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
精彩评论