开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜