Obtenez le premier et le dernier jour du mois en utilisant trois, LocalDate

127

J'ai un LocalDate qui doit obtenir le premier et le dernier jour du mois. Comment je fais ça?

par exemple. 13/2/2014 J'ai besoin d'obtenir 1/2/2014et 28/2/2014dans les formats LocalDate .

Utilisation de trois classes LocalDate.

user1746050
la source

Réponses:

180

Utilisez simplement withDayOfMonthet lengthOfMonth():

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());
Jon Skeet
la source
3
Pour info, voir d'autres réponses
assylias
147

L'API a été conçue pour prendre en charge une solution qui correspond étroitement aux exigences de l'entreprise

import static java.time.temporal.TemporalAdjusters.*;

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());

Cependant, les solutions de Jon sont également très bien.

JodaStephen
la source
5
Avec celui-ci, utilise les ressources API spécialement conçues pour gérer ce problème particulier.
jpangamarca
89

YearMonth

Pour être complet, et plus élégant à mon avis, voyez cette utilisation de la YearMonthclasse.

YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end   = month.atEndOfMonth();

Pour le premier et le dernier jour du mois en cours, cela devient:

LocalDate start = YearMonth.now().atDay(1);
LocalDate end   = YearMonth.now().atEndOfMonth();
Herman
la source
8
La meilleure solution de toutes.
Agustí Sánchez
Informations supplémentaires: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
egemen
quels en sont les avantages par rapport à la LocalDate withméthode?
AndrewBloom
@AndrewBloom vous n'avez pas besoin d'utiliser une fonction statique pour obtenir le dernier jour du mois, et au moins dans le deuxième exemple, vous n'avez pas besoin d'avoir une LocalDateinstance pour commencer.
herman
18

La réponse de Jon Skeets est juste et a mérité mon vote favorable, en ajoutant simplement cette solution légèrement différente pour être complète:

import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.with(lastDayOfMonth());
Meno Hochschild
la source
2
Cher downvote, honnêtement, je ne comprends pas le downvote parce que ma réponse était même un jour avant celle de JodaStephen et a souligné la nouvelle partie principalement intéressante, à savoir l'ajustement temporel pour la fin du mois. C'est-à-dire que je n'ai "copié" la réponse de personne d'autre.
Meno Hochschild
Très bonne réponse! Cette solution est meilleure car elle est recommandée dans la documentation : "... trouver le premier ou le dernier jour du mois"
peterchaula
4

Si quelqu'un vient chercher le premier jour du mois précédent et le dernier jour du mois précédent :

public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
        return date.minusMonths(1).withDayOfMonth(1);
    }


public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
        return date.withDayOfMonth(1).minusDays(1);
    }
Anil Bhaskar
la source
Bon code, mais dans Stack Overflow, une réponse doit aborder les spécificités de la question.
Basil Bourque
Merci, je suis d'accord. Parfois, nous trouvons du code associé dans le fil, car je suis également venu le chercher. Je viens de le mettre pour de tels utilisateurs. J'espère que ça va. Merci.
Anil Bhaskar
3
 LocalDate monthstart = LocalDate.of(year,month,1);
 LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);
Dersu
la source
Veuillez décrire votre réponse
smilyface le
1

Vous pouvez essayer ceci pour éviter d'indiquer une date personnalisée et s'il est nécessaire d'afficher les dates de début et de fin du mois en cours:

    LocalDate start = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()-1);
    LocalDate end = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()).plusMonths(1);
    System.out.println("Start of month: " + start);
    System.out.println("End of month: " + end);

Résultat:

>     Start of month: 2019-12-01
>     End of month: 2019-12-30
VS
la source
1
Cela me semble un peu trop compliqué. Cela ne donne pas non plus le résultat correct. Le dernier jour de ce mois est le 31/12/2019, mais votre extrait est imprimé 30/12/2019.
Ole VV
0

Essaye ça:

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);         
LocalDate end = initial.withDayOfMonth(initial.getMonthOfYear().getLastDayOfMonth(false));
System.out.println(start);
System.out.println(end);

vous pouvez trouver la sortie désirée mais vous devez prendre soin du paramètre true / false pour la méthode getLastDayOfMonth

ce paramètre indique une année bissextile

Shekhar Rajput
la source
Il n'y a pas besoin d'utiliser getLastDayOfMonth- voir ma réponse pour une approche plus simple.
Jon Skeet
0

si vous voulez le faire uniquement avec la classe LocalDate:

LocalDate initial = LocalDate.of(2014, 2, 13);

LocalDate start = LocalDate.of(initial.getYear(), initial.getMonthValue(),1);

// Idea: the last day is the same as the first day of next month minus one day.
LocalDate end = LocalDate.of(initial.getYear(), initial.getMonthValue(), 1).plusMonths(1).minusDays(1);
MrSmith42
la source
0

Juste ici pour montrer mon implémentation pour la solution @herman

ZoneId americaLaPazZone = ZoneId.of("UTC-04:00");

static Date firstDateOfMonth(Date date) {
  LocalDate localDate = convertToLocalDateWithTimezone(date);
  YearMonth baseMonth = YearMonth.from(localDate);
  LocalDateTime initialDate = baseMonth.atDay(firstDayOfMonth).atStartOfDay();
  return Date.from(initialDate.atZone(americaLaPazZone).toInstant());
}

static Date lastDateOfMonth(Date date) {
  LocalDate localDate = convertToLocalDateWithTimezone(date);
  YearMonth baseMonth = YearMonth.from(localDate);
  LocalDateTime lastDate = baseMonth.atEndOfMonth().atTime(23, 59, 59);
  return Date.from(lastDate.atZone(americaLaPazZone).toInstant());
}

static LocalDate convertToLocalDateWithTimezone(Date date) {
  return LocalDateTime.from(date.toInstant().atZone(americaLaPazZone)).toLocalDate();
}
Luis Roberto
la source
LocalDateTimeest exactement la mauvaise classe à utiliser ici. Vous supprimez des informations de zone / offset précieuses.
Basil Bourque
La question demande une valeur de date uniquement, pas les valeurs de date avec heure que vous recherchez ici. Et la classe de l'héritage terrible Daten'a rien à voir avec la question, et devrait généralement être évitée.
Basil Bourque
1
Pour le fuseau horaire de La Paz, veuillez utiliser le plus correct ZoneId.of("America/La_Paz"). Pour les dates actuelles, cela donnera le même résultat, mais peut-être pas pour des dates historiques ou des dates dans un futur futur.
Ole VV