Search code examples
javajava-8calendarlocaldatelocaldatetime

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?


Solution

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