En el tiempo de Joda, establezca el tiempo de entrada para comenzar el mes
Pregunta
Mi API permite que el cliente de la biblioteca pase la fecha:
method(java.util.Date date)
Trabajando con Joda-tiempo, desde esta fecha, me gustaría extraer el mes e iterar durante todos los días este mes contiene.
Ahora, la fecha pasada suele ser nueva fecha () - Significa un instante actual. Mi problema en realidad es establecer el nuevo Datemidnight (jdkdate) instancia para ser a principios de mes.
¿Podría alguien demostrar este caso de uso con Joda-tiempo?
Solución
La medianoche al comienzo del primer día del mes actual está dada por:
// first midnight in this month
DateMidnight first = new DateMidnight().withDayOfMonth(1);
// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);
Si comienza desde un Java.util.Date, se utiliza un constructor de noches de Datemid diferente:
// first midnight in java.util.Date's month
DateMidnight first = new DateMidnight( date ).withDayOfMonth(1);
Joda Time Java Doc - https://www.joda.org/joda tiempo/apidocs/overview-summary.html
Otros consejos
Una forma alternativa (sin tener en cuenta Datemidnight) para tener el primer día del mes sería usar:
DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
Primer momento del día
los Respuesta de Ngeek es correcto, pero no pasa el tiempo al primer momento del día. Para ajustar el tiempo, agregue una llamada a withTimeAtStartOfDay
.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
org.joda.time.DateTime startOfThisMonth = new org.joda.time.DateTime().dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
org.joda.time.DateTime startofNextMonth = startOfThisMonth.plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
System.out.println( "startOfThisMonth: " + startOfThisMonth );
System.out.println( "startofNextMonth: " + startofNextMonth );
Cuando corre en Seattle nosotros ...
startOfThisMonth: 2013-11-01T00:00:00.000-07:00
startofNextMonth: 2013-12-01T00:00:00.000-08:00
Tenga en cuenta la diferencia en esas dos líneas de salida de consola: -7 vs -8 debido a Horario de verano.
En general, se debe especificar la zona horaria en lugar de confiar en el valor predeterminado. Omitido aquí por simplicidad. Uno debe agregar una línea como esta y pasar el objeto de zona horaria a los constructores utilizados en el ejemplo anterior.
// Time Zone list: http://joda-time.sourceforge.net/timezones.html (Possibly out-dated, read note on that page)
// UTC time zone (no offset) has a constant, so no need to construct: org.joda.time.DateTimeZone.UTC
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );
java.time
Lo anterior es correcto pero desactualizado. La biblioteca del tiempo Joda ahora suplanta por el marco Java.Time integrado en Java 8 y más tarde.
los LocalDate
representa un valor de solo fecha sin hora del día y sin zona horaria. Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía según la zona de todo el mundo.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
Usa uno de los TemporalAdjusters
para obtener el primer mes.
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
los LocalDate
puede generar un ZonedDateTime
Eso representa el primer momento del día.
ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
Oh, no vi que se tratara de Jodatime. De todos modos:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
int min = c.getActualMinimum(Calendar.DAY_OF_MONTH);
int max = c.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = min; i <= max; i++) {
c.set(Calendar.DAY_OF_MONTH, i);
System.out.println(c.getTime());
}
O usando Commons-Lang:
Date min = DateUtils.truncate(date, Calendar.MONTH);
Date max = DateUtils.addMonths(min, 1);
for (Date cur = min; cur.before(max); cur = DateUtils.addDays(cur, 1)) {
System.out.println(cur);
}
DateMidnight
ahora está en desuso. En su lugar, puedes hacer:
LocalDate firstOfMonth = new LocalDate(date).withDayOfMonth(1);
LocalDate lastOfMonth = firstOfMonth.plusMonths(1).minusDays(1);
Si sabe que usa la zona horaria new LocalDate(date, timeZone)
en su lugar para mayor precisión.
TAMBIÉN PUEDES HACER .dayOfMonth().withMinimumValue()
en vez de .withDayOfMonth(1)
EDITAR:
Esto te dará 12/1/YYYY 00:00
y 12/31/YYYY 00:00
. Si prefiere que el último mes sea en realidad el primero del próximo mes (porque está haciendo una cláusula entre), retire el minusDays(1)
Del cálculo de LastOfMonth