Reputation: 1671
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
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.
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 simplyInstant instant = calendar.toInstant();
. For creating a sample old-fashionedCalendar
I would use likeGregorianCalendar.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
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