Je voudrais obtenir la date du premier jour de la semaine sur la base de LocalDate.now (). Ce qui suit était possible avec JodaTime, mais semble avoir été supprimé de la nouvelle API Date de Java 8.
LocalDate now = LocalDate.now();
System.out.println(now.withDayOfWeek(DateTimeConstants.MONDAY));
Je ne peux pas appeler 'withDayOfWeek ()', car il n'existe pas.
Ma question est donc la suivante: Comment obtenir la date du premier jour de la semaine en fonction d’une date locale?
Notez que l'expression System.out.println(now.with(DayOfWeek.MONDAY))
dépend des paramètres régionaux, car elle utilise ISO-8601. Par conséquent, elle revient toujours en arrière jusqu'au lundi dernier (ou reste lundi si la date est déjà fixée à lundi).
Ainsi, aux États-Unis ou dans certains autres pays - où la semaine commence le dimanche - cela ne fonctionnera peut-être pas comme prévu - now.with(DayOfWeek.MONDAY)
ne fera pas un bond en avant jusqu'à lundi, si la date indique dimanche.
Si vous avez besoin de résoudre ces problèmes, il est préférable d’utiliser le champ localisé WeekFields.dayOfWeek () :
LocalDate now = LocalDate.now();
TemporalField fieldISO = WeekFields.of(Locale.FRANCE).dayOfWeek();
System.out.println(now.with(fieldISO, 1)); // 2015-02-09 (Monday)
TemporalField fieldUS = WeekFields.of(Locale.US).dayOfWeek();
System.out.println(now.with(fieldUS, 1)); // 2015-02-08 (Sunday)
Un autre exemple dû aux commentaires ci-dessous:
LocalDate ld = LocalDate.of(2017, 8, 18); // Friday as original date
System.out.println(
ld.with(DayOfWeek.SUNDAY)); // 2017-08-20 (2 days later according to ISO)
// Now let's again set the date to Sunday, but this time in a localized way...
// the method dayOfWeek() uses localized numbering (Sunday = 1 in US and = 7 in France)
System.out.println(ld.with(WeekFields.of(Locale.US).dayOfWeek(), 1L)); // 2017-08-13
System.out.println(ld.with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 7L)); // 2017-08-20
L'exemple américain montre assez clairement que quelqu'un résidant aux États-Unis s'attendrait à rester le dernier et non au dimanche prochain, car dimanche est considéré comme le premier jour de la semaine aux États-Unis. La simple expression basée sur ISO with(DayOfWeek.SUNDAY)
ignore ce problème de localisation.
Essayer
System.out.println(now.with(DayOfWeek.MONDAY));
Merci à viens de à cette question .
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
System.out.println("Start of this week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
Comme le correct Answer de Ray dit, vous pouvez appeler with
et passer le DayOfWeek
enum.
Notez que le fuseau horaire est crucial pour déterminer la date de "aujourd'hui". A tout moment, la date varie selon votre position sur le globe.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate firstDayOfThisWeek = LocalDate.now ( zoneId ).with ( DayOfWeek.MONDAY );
Si vous ne spécifiez pas de fuseau horaire, le fuseau horaire par défaut de la machine virtuelle Java est appliqué en mode silencieux. Attention: cette valeur par défaut peut changer à tout moment pendant l'exécution! Mieux vaut spécifier votre fuseau horaire souhaité/attendu .
ZonedDateTime
Vous pouvez appliquer un fuseau horaire (a ZoneId
) à votre LocalDate
pour obtenir un ZonedDateTime
représentant le premier moment de la semaine.
ZonedDateTime thisWeekStart = firstDayOfThisWeek.atStartOfDay ( zoneId );
LocalDate ne semble pas avoir cela, mais WeekFields (qui provient de l'API Java-8) en a ( here ). Donc, vous pouvez faire ceci:
WeekFields.of(Locale.getDefault()).firstDayOfWeek.value
Ceci retourne la valeur du premier jour de la semaine, commençant de 1 à lundi et se terminant à 7 à dimanche.
Exemple d'utilisation (en Kotlin), pour obtenir une nouvelle date locale qui a la valeur dayOfWeek, en remontant dans le temps au lieu d'avancer:
/**@param targetDayOfWeek day of week to go to, starting from 1 as Monday (and 7 is Sunday) */
fun LocalDate.minusDaysToDayOfWeek(targetDayOfWeek: Int = WeekFields.of(Locale.getDefault()).firstDayOfWeek.value): LocalDate {
//conversion so that Sunday is 0, Monday is 1, etc:
val diffDays = (dayOfWeek.value % 7) - (targetDayOfWeek % 7)
val result = when {
diffDays == 0 -> this
diffDays < 0 -> minusDays((7 + diffDays).toLong())
else -> minusDays(diffDays.toLong())
}
return result
}
Exemple d'entrées-sorties:
2017-12-31 -> 2017-12-31
2018-01-01 -> 2017-12-31
2018-01-02 -> 2017-12-31
2018-01-03 -> 2017-12-31
2018-01-04 -> 2017-12-31
2018-01-05 -> 2017-12-31
2018-01-06 -> 2017-12-31
2018-01-07 -> 2018-01-07
2018-01-08 -> 2018-01-07
2018-01-09 -> 2018-01-07
2018-01-10 -> 2018-01-07
2018-01-11 -> 2018-01-07
2018-01-12 -> 2018-01-07
2018-01-13 -> 2018-01-07
2018-01-14 -> 2018-01-14
2018-01-15 -> 2018-01-14
Et voici un exemple de fonction pour avancer dans le temps jusqu'au jour de la semaine cible:
fun LocalDate.plusDaysToDayOfWeek(targetDayOfWeek: Int = getLastDayOfWeek()): LocalDate {
val diffDays = (targetDayOfWeek % 7) - (dayOfWeek.value % 7)
val result = when {
diffDays == 0 -> this
diffDays < 0 -> plusDays((7 + diffDays).toLong())
else -> plusDays(diffDays.toLong())
}
return result
}
/**@return the last day of week, when 1 is Monday ... 7 is Sunday) */
@JvmStatic
fun getLastDayOfWeek(firstDayOfWeek: DayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek): Int {
return when (firstDayOfWeek) {
DayOfWeek.MONDAY -> DayOfWeek.SUNDAY.value
else -> firstDayOfWeek.value - 1
}
}
BTW, chose étrange, c'est que je pense que le code dans les coulisses de la nouvelle API utilise en fait la classe Calendar de toute façon ...
Si vous détestez utiliser dayOfWeek comme pour LocalDate (comme je le fais) et que vous préférez celui utilisé avec Calendar, vous pouvez utiliser ces convertisseurs simples:
fun DayOfWeek.toCalendarDayOfWeek(): Int {
return when (this) {
DayOfWeek.SATURDAY -> Calendar.SATURDAY
else -> (this.value + 1) % 7
}
}
@JvmStatic
fun convertLocalDateDayOfWeekToCalendarDayOfWeek(localDateDayOfWeek: Int): Int {
return when (localDateDayOfWeek) {
DayOfWeek.SATURDAY.value -> Calendar.SATURDAY
else -> (localDateDayOfWeek + 1) % 7
}
}
@JvmStatic
fun convertFromCalendarDayOfWeekToLocalDateDayOfWeek(calendarDayOfWeek: Int): Int {
return when (calendarDayOfWeek) {
Calendar.SUNDAY -> DayOfWeek.SUNDAY.value
else -> calendarDayOfWeek - 1
}
}
Avec Joda Time, que pensez-vous de
now.toString("EEEE", locale)
Cela fonctionne pour moi au cas où je voudrais recevoir lundi comme premier jour de la semaine en cours:
LocalDate mondayDate = LocalDate.now().with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());