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.

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());

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.


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();

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());

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);
    }

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);

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

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


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);

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();
}

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.