J'ai des problèmes avec le calcul du moment où le dernier jour du mois doit être envoyé pour l'envoi d'une notification.
Voici mon code:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
C’est la ligne qui cause des problèmes, je crois:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
Comment utiliser le calendrier pour définir correctement le dernier jour du mois suivant pour la notification?
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
Ceci renvoie le maximum actuel pour le mois en cours. Par exemple, il s’agit du mois de février de l’année bissextile. Il renvoie donc 29 sous la forme int
.
En utilisant la bibliothèque Java.time
intégrée à Java 8, vous pouvez utiliser la classe TemporalAdjuster
(ou la classe TemporalAdjusters
) )
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
Si vous devez ajouter des informations sur l'heure, vous pouvez utiliser n'importe quelle conversion LocalDate en LocalDateTime disponible, comme
lastDay.atStartOfDay(); //2015-11-30T00:00
Et pour obtenir le dernier jour comme objet Date:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
Date lastDayOfMonth = cal.getTime();
Vous pouvez définir le calendrier au début du mois prochain, puis soustraire un jour.
Calendar nextNotifTime = Calendar.getInstance();
nextNotifTime.add(Calendar.MONTH, 1);
nextNotifTime.set(Calendar.DATE, 1);
nextNotifTime.add(Calendar.DATE, -1);
Après avoir exécuté ce code, nextNotifTime sera défini sur le dernier jour du mois en cours. N'oubliez pas que si aujourd'hui est le dernier jour du mois, l'effet net de ce code est que l'objet Calendar reste inchangé.
Suivre donnera toujours les bons résultats:
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();
En utilisant la dernière bibliothèque Java.time
_, voici la meilleure solution:
LocalDate date = LocalDate.now();
LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
Alternativement, vous pouvez faire:
LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
Examinez la méthode getActualMaximum(int field)
de l'objet Calendar.
Si vous définissez votre objet Calendrier comme étant le mois pour lequel vous recherchez la dernière date, alors getActualMaximum(Calendar.DAY_OF_MONTH)
vous donnera le dernier jour.
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));
Vous pouvez également utiliser YearMonth.
Comme:
YearMonth.of(2019,7).atEndOfMonth()
YearMonth.of(2019,7).atDay(1)
Voir https://docs.Oracle.com/javase/8/docs/api/Java/time/YearMonth.html#atEndOfMonth--
Mise en œuvre d'une extension de date Kotlin avec 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
}
Vous pouvez appeler la fonction toEndOfMonth
sur chaque objet Date comme Date().toEndOfMonth()