Reputation: 2377
I am having issues with the calculation of when the next Last Day of the Month is for a notification which is scheduled to be sent.
Here is my code:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
This is the line causing issues I believe:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
How can I use the Calendar to properly set the last day of the next month for the notification?
Upvotes: 165
Views: 246880
Reputation: 7486
Using the java.time
library built into Java 8, you can use the TemporalAdjuster
interface. We find an implementation ready for use in the TemporalAdjusters
utility class: lastDayOfMonth
.
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
LocalDate now = LocalDate.now(); //2015-11-23
LocalDate lastDay = now.with(TemporalAdjusters.lastDayOfMonth()); //2015-11-30
If you need to add time information, you may use any available LocalDate
to LocalDateTime
conversion like
lastDay.atStartOfDay(); //2015-11-30T00:00
Upvotes: 75
Reputation: 141
You can also use YearMonth.
Like:
YearMonth.of(2019,7).atEndOfMonth()
YearMonth.of(2019,7).atDay(1)
See https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html#atEndOfMonth--
Upvotes: 12
Reputation: 667
Kotlin date extension implementation using java.util.Calendar
fun Date.toEndOfMonth(): Date {
return Calendar.getInstance().apply {
time = this@toEndOfMonth
}.toEndOfMonth().time
}
fun Calendar.toEndOfMonth(): Calendar {
set(Calendar.DAY_OF_MONTH, getActualMaximum(Calendar.DAY_OF_MONTH))
return this
}
You can call toEndOfMonth
function on each Date object like Date().toEndOfMonth()
Upvotes: 3
Reputation: 115418
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
This returns actual maximum for current month. For example it is February of leap year now, so it returns 29 as int
.
Upvotes: 389
Reputation: 939
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse("11/02/2016");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
System.out.println("First Day Of Month : " + calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
System.out.println("Last Day of Month : " + calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Upvotes: 2
Reputation: 11494
Using the latest java.time
library here is the best solution:
LocalDate date = LocalDate.now();
LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
Alternatively, you can do:
LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
Upvotes: 10
Reputation: 395
Following will always give proper results:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, ANY_MONTH);
cal.set(Calendar.YEAR, ANY_YEAR);
cal.set(Calendar.DAY_OF_MONTH, 1);// This is necessary to get proper results
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
cal.getTime();
Upvotes: 21
Reputation: 3268
And to get last day as Date object:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
Date lastDayOfMonth = cal.getTime();
Upvotes: 40
Reputation: 94
Look at the getActualMaximum(int field)
method of the Calendar object.
If you set your Calendar object to be in the month for which you are seeking the last date, then getActualMaximum(Calendar.DAY_OF_MONTH)
will give you the last day.
Upvotes: 3
Reputation: 18397
You can set the calendar to the first of next month and then subtract a day.
Calendar nextNotifTime = Calendar.getInstance();
nextNotifTime.add(Calendar.MONTH, 1);
nextNotifTime.set(Calendar.DATE, 1);
nextNotifTime.add(Calendar.DATE, -1);
After running this code nextNotifTime will be set to the last day of the current month. Keep in mind if today is the last day of the month the net effect of this code is that the Calendar object remains unchanged.
Upvotes: 22