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.