Dado un Objeto Date, ¿cómo puedo determinar el último día de su mes?
Pregunta
Estoy tratando de utilizar el siguiente código pero es devolver el mal día del mes.
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.set(Calendar.MONTH, sampleDay.get(Calendar.MONTH)+1);
cal.set(Calendar.DAY_OF_MONTH, 0);
return cal.getTime();
Solución
Obtener el número de días de este mes:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
int noOfLastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
Establecer el Calendario para el último día de este mes:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Otros consejos
Me gustaría crear un objeto date para el primer día del mes SIGUIENTE y, a continuación, sólo resta un solo día a partir de la fecha de objetos.
tl;dr
YearMonth.from(
LocalDate.now( ZoneId.of( "America/Montreal" ) )
).atEndOfMonth()
java.tiempo
La Pregunta y el otro Responde utilice el viejo anticuado de las clases.Han sido suplantados por la java.tiempo clases construido en Java 8 y versiones posteriores.Ver Oracle Tutorial.Gran parte de la funcionalidad ha sido nuevamente trasladado a Java 6 y 7 en ThreeTen-Backport y más adaptado a Android en ThreeTenABP.
LocalDate
El LocalDate
clase representa una fecha valor solo sin la hora del día y sin zona horaria.Mientras que estos objetos de la tienda sin zona horaria, tenga en cuenta que la zona horaria es crucial en la determinación de la fecha actual.Para un momento dado de la fecha varía en todo el mundo por el tiempo de la zona.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId ); // 2016-06-25
YearMonth
Se combinan con la YearMonth
de la clase para determinar el último día de cualquier mes.
YearMonth currentYearMonth = YearMonth.from( today ); // 2016-06
LocalDate lastDayOfCurrentYearMonth = currentYearMonth.atEndOfMonth(); // 2016-06-30
Por el camino, LocalDate
y YearMonth
mes de los números tal como se esperaría (1-12) en lugar de la screwball 0-11 visto en el antiguo fecha y la hora de clases.Uno de los muchos pobres de las decisiones de diseño que hacen que esos viejos fecha y la hora de clases, lo problemático y confuso.
TemporalAdjuster
Es otro enfoque válido el uso de un TemporalAdjuster
.Ver la Respuesta correcta por Pierre Henry.
Uso calObject.getActualMaximum(calobject.DAY_OF_MONTH)
Ver Real de Java de Cómo-a para más información sobre esto.
Parece que se establece el calendario para el primer día del mes siguiente, por lo que necesita una línea más para restar un día, para obtener el último día del mes en que sampleDay está en:
Calendar cal = Calendar.getInstance();
cal.setTime(sampleDay.getTime());
cal.roll(Calendar.MONTH, true);
cal.set(Calendar.DAY_OF_MONTH, 0);
cal.add(Calendar.DAY_OF_MONTH, -1);
En general, es mucho más fácil hacer este tipo de cosas usando Joda Tiempo, por ejemplo:
DateTime date = new DateTime(sampleDay.getTime());
return date.plusMonths(1).withDayOfMonth(0).minusDays(1).getMillis();
TemporalAdjuster
El uso de la (relativamente) nuevo Java fecha de la API, es realmente muy fácil :
Vamos date
ser una instancia de LocalDate
, por ejemplo :
LocalDate date = LocalDate.of(2018, 1, 22);
o
LocalDate date = LocalDate.now();
o, por supuesto, usted podría conseguir una entrada del usuario, a partir de una base de datos, etc.
A continuación, aplicar una implementación de la TemporalAdjuster
interfaz que se encuentra en la TemporalAdjusters
clase:
LocalDate first = date.with(TemporalAdjusters.firstDayOfMonth());
LocalDate last = date.with(TemporalAdjusters.lastDayOfMonth());
Si utiliza el date4j biblioteca:
DateTime monthEnd = dt.getEndOfMonth();
Creo que esto debería funcionar bien:
Dim MyDate As Date = #11/14/2012# 'This is just an example date
MyDate = MyDate.AddDays(DateTime.DaysInMonth(MyDate.Year, MyDate.Month) - MyDate.Day)