java12399900
java12399900

Reputation: 1671

Java - issues comparing Calendar to LocalDateTime?

I have the following comparison in my Java code:

if(appointment.getEndDate().after(LocalDateTime.now()){

//do something
}

note that endDate field is a Calendar type.

Are there any issues with doing a comparison between Calendar and LocalDateTime this way, or is there a better way to do it?

Upvotes: 1

Views: 1753

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79085

Are there any issues with doing a comparison between Calendar and LocalDateTime this way, or is there a better way to do it?

Yes, it will give you an incorrect result. Moreover, the java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.

You should convert the Calendar object into Instant and then you can do the rest of the things using the modern date-time API.

Demo:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        // A sample calendar object
        String strDateTime = "10/02/2021 22:25";
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm", Locale.ENGLISH);
        Date date = sdf.parse(strDateTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        Instant instant = calendar.getTime().toInstant();

        // Change the ZoneId as per your requirement e.g. ZoneId.of("Europe/London")
        ZoneId zoneId = ZoneId.systemDefault();

        ZonedDateTime zdt = instant.atZone(zoneId);

        ZonedDateTime now = ZonedDateTime.now(zoneId);

        System.out.println(zdt.isAfter(now));
    }
}

Output:

true

Learn more about the modern date-time API from Trail: Date Time.


Update

Thanks, Ole V.V. for your valuable feedback:.

If the OP cannot afford to upgrade the appointment class to return a modern type (like ZonedDateTime) for end date-time, this is the way to go. Calendar too has a toInstant method, so you can do with simply Instant instant = calendar.toInstant();. For creating a sample old-fashioned Calendar I would use like GregorianCalendar.from(ZonedDateTime.of(2021, 10, 2, 22, 25, 0, 0, ZoneId.systemDefault()))


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

Upvotes: 4

Yoni
Yoni

Reputation: 1430

You should not compare a Calendar with a LocalDateTime object. As per the documentation, this wil always return false

Returns whether this Calendar represents a time after the time represented by the specified Object. This method is equivalent to:

compareTo(when) > 0

if and only if when is a Calendar instance. Otherwise, the method returns false.

You need to convert your Calendar to a LocalDateTime before comparing it with another LocalDateTime

You can do a conversion with the following code

LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());

Upvotes: 3

Related Questions