Java - 将 Calendar 与 LocalDateTime 进行比较有问题吗?
Java - issues comparing Calendar to LocalDateTime?
我的 Java
代码中有以下比较:
if(appointment.getEndDate().after(LocalDateTime.now()){
//do something
}
请注意 endDate
字段是 Calendar
类型。
用这种方式比较 Calendar
和 LocalDateTime
有什么问题吗?或者有更好的方法吗?
您不应将 Calendar
与 LocalDateTime
对象进行比较。根据文档,这将 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
了解有关现代日期时间 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 。
我的 Java
代码中有以下比较:
if(appointment.getEndDate().after(LocalDateTime.now()){
//do something
}
请注意 endDate
字段是 Calendar
类型。
用这种方式比较 Calendar
和 LocalDateTime
有什么问题吗?或者有更好的方法吗?
您不应将 Calendar
与 LocalDateTime
对象进行比较。根据文档,这将 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
了解有关现代日期时间 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 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()))
* 无论出于何种原因,如果您必须坚持使用 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