55

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.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.

Simon Gibbs
  • 4,737
  • 6
  • 50
  • 80

2 Answers2

78

There are various methods on LocalDate for this, including:

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 11
    Spot on. One thing to be aware of: toDateTimeAtStartOfDay doesn't mean "midnight"... some time zones implement daylight saving changes to skip from midnight to 1am. – Jon Skeet Jan 11 '11 at 10:28
  • You might conclude as I did, that which of the methods (that all return DateTime, like those here) that you choose doesn't really matter: The fact that a LocalDate was used should imply it was coded without any intent for a particular time on that date, so whatever time you give it in the conversion on that date is just as good as any other time on that date. The key is that giving it a time is what allows the conversion to LocalDate, and it doesn't matter what the time is (since you started with a LocalDate that didn't care about time) if all you need is some sort of DateTime. – cellepo Jun 29 '16 at 01:01
  • 3
    Please help - I cannot see any of this methods on my LocalDate object. What does the '::' notation mean in your answer? – Metin Dagcilar Dec 30 '17 at 23:40
1

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110