Java:检查给定日期是否在当前月份内
我需要检查给定的日期是否在当前月份,我编写了以下代码,但IDE提醒我,和方法已经过时。我想知道如何在较新的Java7或Java8中做同样的事情Java:检查给定日期是否在当前月份内,java,date,java-time,java.util.date,Java,Date,Java Time,Java.util.date,我需要检查给定的日期是否在当前月份,我编写了以下代码,但IDE提醒我,和方法已经过时。我想知道如何在较新的Java7或Java8中做同样的事情 private boolean inCurrentMonth(Date givenDate) { Date today = new Date(); return givenDate.getMonth() == today.getMonth() && givenDate.getYear() == today.getYear
private boolean inCurrentMonth(Date givenDate) {
Date today = new Date();
return givenDate.getMonth() == today.getMonth() && givenDate.getYear() == today.getYear();
}
据我所知,Calendar类及其派生的所有类都使用get()返回日期。看。这里还有一个例子: 哪个输出
2013 Feb 28 13:24:56
year : 2013
month : 1
dayOfMonth : 28
dayOfWeek : 5
weekOfYear : 9
weekOfMonth : 5
hour : 1
hourOfDay : 13
minute : 24
second : 56
millisecond : 0
我认为它被取代是因为新方法使用单个函数提供了更简单的处理,更容易记住。时区
//Create 2 instances of Calendar
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
//set the given date in one of the instance and current date in the other
cal1.setTime(givenDate);
cal2.setTime(new Date());
//now compare the dates using methods on Calendar
if(cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) {
if(cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)) {
// the date falls in current month
}
}
其他答案忽略了时区这一关键问题。巴黎新的一天比蒙特勒尔早,所以在同一时刻,巴黎的“明天”和蒙特勒尔的“昨天”的日期是不同的
乔达时间
与java捆绑在一起的java.util.Date和.Calendar类是出了名的麻烦、混乱和缺陷。避开它们
而是使用java 8中的库或java.time包(受Joda time启发)
下面是Joda Time2.5中的示例代码
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime = new DateTime( yourJUDate, zone ); // Convert java.util.Date to Joda-Time, and assign time zone to adjust.
DateTime now = DateTime.now( zone );
// Now see if the month and year match.
if ( ( dateTime.getMonthOfYear() == now.getMonthOfYear() ) && ( dateTime.getYear() == now.getYear() ) ) {
// You have a hit.
}
要查看某个时刻是否在任何时间跨度内(而不仅仅是一个月),请在StackOverflow中搜索“joda”和“interval”以及“contain”。java.time(java 8)
使用新的API()有几种方法。您可以使用.get(ChronoField.XY)
来执行此操作,但我认为这更漂亮:
Instant given = givenDate.toInstant();
Instant ref = Instant.now();
return Month.from(given) == Month.from(ref) && Year.from(given).equals(Year.from(ref));
为了更好的可重用性,您还可以将此代码重构为“临时查询”:
公共类临时查询{
//临时查询{R queryFrom(TemporalAccessor temporal)}
公共静态布尔值isCurrentMonth(临时Accessor临时){
Instant ref=Instant.now();
返回月从(时间)=月从(参考)和年从(时间)。等于(年从(参考));
}
}
布尔结果=givenDate.toInstant().query(临时查询::iscurrentmount)//Lambda使用方法参考
java.time(java 8)
Java 8提供的类表示给定年份内的给定月份(例如2018年1月)。这可用于与给定日期的YearMonth
进行比较
private boolean inCurrentMonth(Date givenDate) {
ZoneId timeZone = ZoneOffset.UTC; // Use whichever time zone makes sense for your use case
LocalDateTime givenLocalDateTime = LocalDateTime.ofInstant(givenDate.toInstant(), timeZone);
YearMonth currentMonth = YearMonth.now(timeZone);
return currentMonth.equals(YearMonth.from(givenLocalDateTime));
}
请注意,这种方法适用于任何同时具有月份和日期部分的Java 8时间类(
LocalDate
,ZonedDateTime
,等等),而不仅仅是LocalDateTime
阅读每个方法的JavaDoc,它告诉您应该使用什么。(Java7的扰流板:Calendar.get(Calendar.MONTH)
和Calendar.get(Calendar.YEAR)
)看到Java.time的运行非常有趣。也许可以加上时区?人们很少需要date/month/year of.YearMonth ref=YearMonth.from(LocalDate.now());返回月从(时间)=月从(参考)和年从(时间)。等于(年从(参考));请使用YearMonth for ref.@Arundev注意,YearMonth
可以直接使用.equals()
进行比较,而不是单独比较属性,另外它还有自己的now()
方法:YearMonth ref=YearMonth.now();返回YearMonth.from(时态)等于(ref)代码>好答案。但是使用LocalDateTime
会产生误导。那节课不能代表一个时刻。最好替换为ZoneDateTime
,否则代码将保持不变。您应该添加一条说明,说明在适合业务场景的任何时区中使用ZoneId
。@BasilBourque Beyond my现有的//使用对您的用例有意义的时区
注释?很好。我仍然建议将ZonedDateTime
替换为LocalDateTime
。您当前的代码解决方案恰好适用于这一特定情况,这是一种误导和混淆。扩展该代码的人可能会使用LocalDateTime
而不是ZonedDateTime
@BasilBourque,从而导致错误的结果。我不认为LocalDateTime
可能是个问题。实际上,我们只关心它是一种既有年又有月的Java8类型,并且我们在日期转换和确定当前月份时使用相同的区域LocalDateTime.of instant
将为我们提供特定时刻的正确年份和月份(以及我们实际上并不关心的日期和时间)。如果有一个从Instant
到YearMonth
的直接转换,我会用它来代替。
public class TemporalQueries {
//TemporalQuery<R> { R queryFrom(TemporalAccessor temporal) }
public static Boolean isCurrentMonth(TemporalAccessor temporal) {
Instant ref = Instant.now();
return Month.from(temporal) == Month.from(ref) && Year.from(temporal).equals(Year.from(ref));
}
}
Boolean result = givenDate.toInstant().query(TemporalQueries::isCurrentMonth); //Lambda using method reference
private boolean inCurrentMonth(Date givenDate) {
ZoneId timeZone = ZoneOffset.UTC; // Use whichever time zone makes sense for your use case
LocalDateTime givenLocalDateTime = LocalDateTime.ofInstant(givenDate.toInstant(), timeZone);
YearMonth currentMonth = YearMonth.now(timeZone);
return currentMonth.equals(YearMonth.from(givenLocalDateTime));
}