¿Cómo obtener la primera fecha y la última fecha del mes anterior? (Java)

Con la fecha de hoy, debería obtener la primera fecha y la última fecha del mes anterior. No puedo encontrar ninguna lógica.

Por ejemplo, al aprobar el 05/30/2012 , debería recibir el 04/01/2012 y el 04/30/2012 .

Cualquier ayuda será muy apreciada. Gracias.

Con Calendar

 Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, -1); cal.set(Calendar.DATE, 1); Date firstDateOfPreviousMonth = cal.getTime(); cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE)); // changed calendar to cal Date lastDateOfPreviousMonth = cal.getTime(); 

Ver

  • demo de ideone

tl; dr

 YearMonth.now().minusMonths( 1 ).atDay( 1 ) 

…y…

 YearMonth.now().minusMonths( 1 ).atEndOfMonth() 

Evita juDate

Evite las clases incluidas java.util.Date y .Calendar ya que son notoriamente problemáticas. En su lugar, use el paquete java.time en Java 8 y versiones posteriores.

java.time

El nuevo marco java.time en Java 8 ( Tutorial ) tiene comandos para esto.

La clase YearMonth llamada YearMonth , representa un mes de un año, sin ningún día o tiempo específico. Desde allí podemos solicitar el primer y último día del mes.

 ZonedId zoneId = ZoneId.of( "America/Montreal" ); YearMonth yearMonthNow = YearMonth.now( zoneId ); YearMonth yearMonthPrevious = yearMonthNow.minusMonths( 1 ); LocalDate firstOfMonth = yearMonthPrevious.atDay( 1 ); LocalDate lastOfMonth = yearMonthPrevious.atEndOfMonth(); 

Joda-Time

ACTUALIZACIÓN: El proyecto Joda-Time ahora está en modo de mantenimiento , y el equipo recomienda la migración a las clases java.time . Ver Tutorial de Oracle .

En Joda-Time 2.8, use la clase LocalDate si no le importa la hora del día.

 LocalDate today = LocalDate.now( DateTimeZone.forID( "Europe/Paris" ) ); LocalDate firstOfThisMonth = today.withDayOfMonth( 1 ); LocalDate firstOfLastMonth = firstOfThisMonth.minusMonths( 1 ); LocalDate endOfLastMonth = firstOfThisMonth.minusDays( 1 ); 

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Use un controlador JDBC que cumpla con JDBC 4.2 o posterior. Sin necesidad de cadenas, sin necesidad de clases java.sql.* .

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ….

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .

Use JodaTime

 DateMidnight now = new DateMidnight(); DateMidnight beginningOfLastMonth = now.minusMonths(1).withDayOfMonth(1); DateMidnight endOfLastMonth = now.withDayOfMonth(1).minusDays(1); System.out.println(beginningOfLastMonth); System.out.println(endOfLastMonth); 

Salida:

2012-04-01T00: 00: 00.000 + 02: 00
2012-04-30T00: 00: 00,000 + 02: 00

Explicación: un objeto DateMidnight es un objeto Date sin información de hora del día, que parece justo lo que necesita. De lo contrario, reemplace todas las ocurrencias de DateMidnight con DateTime en el código anterior.

así podría crear un objeto de calendario, establecer la fecha para el primer día del mes actual (debería ser el primero: P) y luego puede hacer dos operaciones: desde su objeto de calendario puede restar un período de tiempo particular, por ejemplo, mes (esto le daría la primera fecha del mes anterior, o un día, que le daría el último día del mes anterior. No lo intenté, pero estos serían mis primeros pasos.

También me gustaría agregar algo a la respuesta de Jigar. Use la clase DateFormat para obtener la fecha en el formato que especificó en la pregunta:

 DateFormat df = DateFormat.getInstance(DateFormat.SHORT); System.out.println(df.format(firstDateOfPreviousMonth)); System.out.println(df.format(lastDateOfPreviousMonth)); 

Salida:

 04/01/12 04/30/12 
  Calendar cal = Calendar.getInstance(); cal.set(Calendar.DATE, 1); cal.add(Calendar.DAY_OF_MONTH, -1); Date lastDateOfPreviousMonth = cal.getTime(); cal.set(Calendar.DATE, 1); Date firstDateOfPreviousMonth = cal.getTime();