Reputation: 18875
I need to check if a given date falls in the current month, and I wrote the following code, but the IDE reminded me that the getMonth()
and getYear()
methods are obsolete. I was wondering how to do the same thing in newer Java 7 or Java 8.
private boolean inCurrentMonth(Date givenDate) {
Date today = new Date();
return givenDate.getMonth() == today.getMonth() && givenDate.getYear() == today.getYear();
}
Upvotes: 8
Views: 37714
Reputation: 21074
Java 8 provides the YearMonth
class which represents a given month within a given year (e.g. January 2018). This can be used to compare against the YearMonth
of the given date.
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));
}
Note that this approach will work for any of the Java 8 time classes that have both a month and a date part (LocalDate
, ZonedDateTime
, etc.) and not just LocalDateTime
.
Upvotes: 5
Reputation: 587
//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
}
}
Upvotes: 18
Reputation: 1297
There are several ways to do it with the new java.time API (tutorial). You can do it using .get(ChronoField.XY)
, but I think this is prettier:
Instant given = givenDate.toInstant();
Instant ref = Instant.now();
return Month.from(given) == Month.from(ref) && Year.from(given).equals(Year.from(ref));
For better re-usability you can also refactor this code to "temporal query":
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
Upvotes: 8
Reputation: 338211
The other answers ignore the crucial issue of time zone. A new day dawns earlier in Paris than in Montréal. So at the same simultaneous moment, the dates are different, "tomorrow" in Paris while "yesterday" in Montréal.
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome, confusing, and flawed. Avoid them.
Instead use either Joda-Time library or the java.time package in Java 8 (inspired by Joda-Time).
Here is example code in Joda-Time 2.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.
}
For a more general solution to see if a moment falls within any span of time (not just a month), search StackOverflow for "joda" and "interval" and "contain".
Upvotes: 6
Reputation: 9681
As far as I know the Calendar class and all derived from it return the date using the get(). See the documentation for this class. Also here is an example taken from here:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMM dd HH:mm:ss");
Calendar calendar = new GregorianCalendar(2013,1,28,13,24,56);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
int weekOfMonth= calendar.get(Calendar.WEEK_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 hour clock
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 hour clock
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int millisecond= calendar.get(Calendar.MILLISECOND);
System.out.println(sdf.format(calendar.getTime()));
System.out.println("year \t\t: " + year);
System.out.println("month \t\t: " + month);
System.out.println("dayOfMonth \t: " + dayOfMonth);
System.out.println("dayOfWeek \t: " + dayOfWeek);
System.out.println("weekOfYear \t: " + weekOfYear);
System.out.println("weekOfMonth \t: " + weekOfMonth);
System.out.println("hour \t\t: " + hour);
System.out.println("hourOfDay \t: " + hourOfDay);
System.out.println("minute \t\t: " + minute);
System.out.println("second \t\t: " + second);
System.out.println("millisecond \t: " + millisecond);
which outputs
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
I think it was replaced because the new way offers a much simpler handling using a single function, which is much easier to remember.
Upvotes: 4