Java - 将 Calendar 与 LocalDateTime 进行比较有问题吗?

Java - issues comparing Calendar to LocalDateTime?

我的 Java 代码中有以下比较:

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

//do something
}

请注意 endDate 字段是 Calendar 类型。

用这种方式比较 CalendarLocalDateTime 有什么问题吗?或者有更好的方法吗?

您不应将 CalendarLocalDateTime 对象进行比较。根据文档,这将 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.

您需要先将您的日历转换为 LocalDateTime,然后再与另一个 LocalDateTime

您可以使用以下代码进行转换

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

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

是的,它会给你一个错误的结果。此外,java.util 日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API*.

您应该将 Calendar 对象转换为 Instant,然后您可以使用现代日期时间 API.

完成其余的事情

演示:

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));
    }
}

输出:

true

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

更新

谢谢,:.

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()))


* 无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用 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