Obtenga el primer y último día del mes usando threeten, LocalDate


127

Tengo un LocalDate que debe obtener el primer y último día del mes. ¿Cómo puedo hacer eso?

p.ej. 13/2/2014 Necesito obtener 1/2/2014y 28/2/2014en formatos LocalDate .

Usando la clase Threeten LocalDate.

Respuestas:


180

Solo usa withDayOfMonthy lengthOfMonth():

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());

3
Para su información vea otras respuestas
assylias

147

La API se diseñó para admitir una solución que se ajusta a los requisitos comerciales.

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

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

Sin embargo, las soluciones de Jon también están bien.


5
Siguiendo con este, utiliza los recursos de la API creados específicamente para manejar este problema en particular.
jpangamarca

87

YearMonth

Para completar, y más elegante en mi opinión, vea este uso de YearMonthclase.

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

Para el primer y último día del mes actual, esto se convierte en:

LocalDate start = YearMonth.now().atDay(1);
LocalDate end   = YearMonth.now().atEndOfMonth();

8
La mejor solución de todas.
Agustí Sánchez

Información adicional: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("aaaaMM"));
egemen

¿Cuáles son sus ventajas en comparación con el LocalDate withmétodo?
AndrewBloom

@AndrewBloom no necesita usar una función estática para obtener el último día del mes, y al menos en el segundo ejemplo, no necesita tener una LocalDateinstancia para comenzar.
herman

18

La respuesta de Jon Skeets es correcta y ha merecido mi voto a favor, simplemente agregando esta solución ligeramente diferente para completar:

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
Estimado votante en contra, honestamente, no entiendo el voto en contra porque mi respuesta fue incluso un día antes que la de JodaStephen y señaló la parte nueva principalmente interesante, a saber, el ajustador temporal para el final del mes. Es decir, no he "copiado" la respuesta de nadie más.
Meno Hochschild

¡Gran respuesta! Esta solución es mejor porque se recomienda en los documentos : "... encontrando el primer o último día del mes"
peterchaula

4

Si alguien viene buscando el primer día del mes anterior y el último día del mes anterior :

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


public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
        return date.withDayOfMonth(1).minusDays(1);
    }

Buen código, pero en Stack Overflow una Respuesta debe abordar los detalles de la Pregunta.
Basil Bourque

Gracias, estoy de acuerdo. A veces encontramos código relacionado en el hilo, ya que vine a buscarlo también. Solo lo puse para tales usuarios. Espero que esté bien. Gracias.
Anil Bhaskar

3
 LocalDate monthstart = LocalDate.of(year,month,1);
 LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);

Por favor describa su respuesta
smilyface

1

Puede intentar esto para evitar indicar una fecha personalizada y si es necesario mostrar las fechas de inicio y finalización del mes actual:

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

Resultado:

>     Start of month: 2019-12-01
>     End of month: 2019-12-30

1
Me parece un poco complicado. Tampoco da el resultado correcto. El último día de este mes es 2019-12-31, pero su fragmento impreso 2019-12-30.
Ole VV

0

Prueba esto:

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

puede encontrar la salida deseada pero debe cuidar el parámetro true / false para el método getLastDayOfMonth

ese parámetro denota año bisiesto


No es necesario usarlo getLastDayOfMonth; vea mi respuesta para un enfoque más simple.
Jon Skeet

0

si desea hacerlo solo con la clase 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

Solo aquí para mostrar mi implementación para la solución @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();
}

LocalDateTimees exactamente la clase incorrecta para usar aquí. Está descartando información valiosa de zona / compensación.
Basil Bourque

La pregunta solicita un valor de solo fecha, no los valores de fecha con hora que busca aquí. Y la terrible clase del legado Dateno tiene nada que ver con la Pregunta y, en general, debería evitarse.
Basil Bourque

1
Para la zona horaria de La Paz, utilice la más correcta ZoneId.of("America/La_Paz"). Para las fechas actuales dará el mismo resultado, pero tal vez no para fechas históricas o fechas en un futuro posterior.
Ole VV
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.