Given a Date Object how do I determine the last day of its month?
Question
I'm trying to use the following code but it's returning the wrong day of month.
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.set(Calendar.MONTH, sampleDay.get(Calendar.MONTH)+1);
cal.set(Calendar.DAY_OF_MONTH, 0);
return cal.getTime();
Solution
Get the number of days for this month:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
int noOfLastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
Set the Calendar to the last day of this month:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
OTHER TIPS
I would create a date object for the first day of the NEXT month, and then just subtract a single day from the date object.
tl;dr
YearMonth.from(
LocalDate.now( ZoneId.of( "America/Montreal" ) )
).atEndOfMonth()
java.time
The Question and other Answers use old outmoded classes. They have been supplanted by the java.time classes built into Java 8 and later. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDate
The LocalDate
class represents a date-only value without time-of-day and without time zone. While these objects store no time zone, note that time zone is crucial in determining the current date. For any given moment the date varies around the globe by time zone.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId ); // 2016-06-25
YearMonth
Combine with the YearMonth
class to determine last day of any month.
YearMonth currentYearMonth = YearMonth.from( today ); // 2016-06
LocalDate lastDayOfCurrentYearMonth = currentYearMonth.atEndOfMonth(); // 2016-06-30
By the way, both LocalDate
and YearMonth
use month numbers as you would expect (1-12) rather than the screwball 0-11 seen in the old date-time classes. One of many poor design decisions that make those old date-time classes so troublesome and confusing.
TemporalAdjuster
Another valid approach is using a TemporalAdjuster
.
See the correct Answer by Pierre Henry.
Use calObject.getActualMaximum(calobject.DAY_OF_MONTH)
See Real's Java How-to for more info on this.
It looks like you set the calendar to the first day of the next month, so you need one more line to subtract one day, to get the last day of the month that sampleDay is in:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.roll(Calendar.MONTH, true);
cal.set(Calendar.DAY_OF_MONTH, 0);
cal.add(Calendar.DAY_OF_MONTH, -1);
In general, it's much easier to do this kind of thing using Joda Time, eg:
DateTime date = new DateTime(sampleDay.getTime());
return date.plusMonths(1).withDayOfMonth(0).minusDays(1).getMillis();
TemporalAdjuster
Using the (relatively) new Java date API, it is actually very easy :
Let date
be an instance of LocalDate
, for example :
LocalDate date = LocalDate.of(2018, 1, 22);
or
LocalDate date = LocalDate.now();
or, of course, you could get it as a user input, from a database, etc.
Then apply an implementation of the TemporalAdjuster
interface found in the TemporalAdjusters
class:
LocalDate first = date.with(TemporalAdjusters.firstDayOfMonth());
LocalDate last = date.with(TemporalAdjusters.lastDayOfMonth());
If you use the date4j library:
DateTime monthEnd = dt.getEndOfMonth();
I think this should work nicely:
Dim MyDate As Date = #11/14/2012# 'This is just an example date
MyDate = MyDate.AddDays(DateTime.DaysInMonth(MyDate.Year, MyDate.Month) - MyDate.Day)