java - 比较月份和年份的两个日期值

pul*_*thi 2 java date date-comparison

我要求匹配两个日期,如果他们的月/年相同,我应该返回true,否则为false.根据我的搜索,我找到了以下解决方案.还有其他更好的方法来进行这种比较吗?

Calendar cal1 = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    cal1.setTime(date1);
    cal2.setTime(date2);
    boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                      cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
Run Code Online (Sandbox Code Playgroud)

Bas*_*que 6

TL;博士

匹配两个日期,如果他们的月/年相同

还有其他更好的方法来进行这种比较吗?

是的,更好的方法是使用现代java.time类.

YearMonth.from(                                   // Represent the year-month without a day-of-month, without a time-of-day, and without a time zone.
    LocalDate.of( 2018 , Month.JANUARY , 23 ) ,   // Represent a date-only, without a time-of-day and without a time zone.
)                                                 // Returns a `YearMonth` object.
.equals(                                          // Compare one `YearMonth` object to another.
    YearMonth.now()                               // Capture today’s year-month as seen in the JVM’s current default time zone.
)
Run Code Online (Sandbox Code Playgroud)

细节

是的,还有更好的方法.

您正在使用与最早版本的Java捆绑在一起的旧日期时间类.事实证明,这些课程设计糟糕,令人困惑且麻烦.避免使用它们,包括java.util.Date.

java.time

这些旧类已被Java 8及更高版本中内置的java.time框架所取代.

Instant

将给定的java.util.Date对象转换为Instant对象,在时间轴上用UTC表示.

Instant i1 = myJavaUtilDate1.toInstant();
Instant i2 = myJavaUtilDate2.toInstant();
Run Code Online (Sandbox Code Playgroud)

我们的目标是获得YearMonth物品,因为您只关心年份和月份.但要实现这一目标,我们需要应用时区.年份和月份仅在特定时区的背景下具有意义,除非您来自冰岛,否则我怀疑您想要UTC的年/月背景.

ZoneId

所以我们需要指定所需/预期的时区(ZoneId).

ZoneId zoneId = ZoneId.of( "America/Montreal" );
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime

将该时区应用于每个时区Instant,生成ZonedDateTime对象.

ZonedDateTime zdt1 = ZonedDateTime.ofInstant( i1 , zoneId );
ZonedDateTime zdt2 = ZonedDateTime.ofInstant( i2 , zoneId );
Run Code Online (Sandbox Code Playgroud)

YearMonth

现在提取YearMonth对象.

YearMonth ym1 = YearMonth.from( zdt1 );
YearMonth ym2 = YearMonth.from( zdt2 );
Run Code Online (Sandbox Code Playgroud)

相比.

Boolean same = ym1.equals( ym2 );
Run Code Online (Sandbox Code Playgroud)

顺便说一下,您可能还有其他涉及年份和月份的业务逻辑.请记住,java.time类现在内置于Java中.因此,您可以YearMonth在整个代码库中使用和传递对象,而不是重新计算或传递字符串.


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.