2010-02-14 16 views
26

Mi API permite a los clientes de la biblioteca para pasar Fecha:En Joda-Hora, ajuste Fecha y hora del comienzo de mes

method(java.util.Date date) 

Trabajar con Joda-Time, a partir de esta fecha me gustaría extraer el mes y iterar sobre todos los días presente mes contiene

Ahora, la fecha aprobada suele ser nueva Fecha() - significado actual instantáneo. Mi problema en realidad es establecer la nueva instancia DateMidnight (jdkDate) al comienzo del mes.

¿Podría alguien demostrar este caso de uso con Joda-Time?

+0

El título de la pregunta debe mencionar Joda Time. –

+0

Lo hace "Podría alguien por favor demuestra este caso de uso con joda-time". He agregado otra nota para que quede más claro que esta es una pregunta de tiempo joda. –

+0

@MaximVeksler Lachlan Roche dijo que * title * debería mencionar a Joda-Time. Hice la edición. –

Respuesta

41

medianoche al comienzo del primer día del mes en curso 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 a partir de una java.util.Date, se utiliza un constructor DateMidnight diferente:

// first midnight in java.util.Date's month 
DateMidnight first = new DateMidnight(date).withDayOfMonth(1); 

Joda Time java doc - http://joda-time.sourceforge.net/api-release/index.html

+0

por cierto, en ese "último" por qué no: DateMidnight last = first.plusMonths (1) .minusDays (1); Lo mismo, simplemente más limpio. –

+1

Esta respuesta fue correcta, pero ahora está pasada de moda. No todos los días en cada zona horaria tiene una medianoche. Joda-Time 2 agregó un método ['withTimeAtStartOfDay'] (http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html#withTimeAtStartOfDay()) para usar en lugar de la" medianoche " caracteristicas. –

+0

DateMidnight ahora está en desuso. Desde JavaDoc: "La hora de la medianoche no existe en algunas zonas horarias donde el cambio de horario de verano salta la medianoche. Use LocalDate para representar una fecha sin zona horaria. O use DateTime para representar una fecha y hora completas, quizás usando DateTime.withTimeAtStartOfDay() para obtener un instante al comienzo del día ". – JustinKSU

5

Oh, no vi que esto fuera sobre 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); 
} 

+0

Gracias por la nota de API básica de java. Aprendí de esto también. –

+0

+1 para el ejemplo de commons-lang, que es práctico – Peter

28

Una forma alternativa (sin tomar DateMidnight en cuenta) para obtener el primer día del mes sería utilizar:

DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue(); 
+5

joda time is awesome – tbruyelle

+5

Aunque la fecha sería el primero del mes, aún sería la hora del mediodía. Agregar .withTimeAtStartOfDay() hasta el final resolvería esto. – JustinKSU

+0

también puede agregar .dayOfMonth(). WithMaximumValue(). HourOfDay(). WithMaximumValue() y puede agregar lo mismo con los minutos de Hours ... para ser más precisos –

7

primer momento del día

El answer by ngeek es correcto, pero no logra ubicar la hora en el primer momento del día. Para ajustar la hora, agregue una llamada al 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 se ejecuta en Seattle Estados Unidos ...

startOfThisMonth: 2013-11-01T00:00:00.000-07:00 
startofNextMonth: 2013-12-01T00:00:00.000-08:00 

Nota la diferencia en esas dos líneas de salida de la consola: -7 -8 vs debido Daylight Saving Time.


En general, uno siempre debe especificar la zona horaria en lugar de confiar en la predeterminada. Omitido aquí por simplicidad. Se 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 correcta pero anticuado. La biblioteca Joda-Time ahora está suplantada por el marco java.time integrado en Java 8 y posterior.

El LocalDate representa un valor de fecha solamente sin hora del día y sin zona horaria.Un huso horario es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía según la zona del mundo.

ZoneId zoneId = ZoneId.of("America/Montreal"); 
LocalDate today = LocalDate.now(zoneId); 

Utilice una de las TemporalAdjusters para conseguir primer día del mes.

LocalDate firstOfMonth = today.with(TemporalAdjusters.firstDayOfMonth()); 

El LocalDate puede generar una ZonedDateTime que representa el primer momento del día.

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay(zoneId); 
-1

DateMidnight ahora está obsoleto. En su lugar puede hacer:

LocalDate firstOfMonth = new LocalDate(date).withDayOfMonth(1); 
LocalDate lastOfMonth = firstOfMonth.plusMonths(1).minusDays(1); 

Si conoce la zona horaria utilizar new LocalDate(date, timeZone) lugar para una mayor precisión.

También se puede hacer en lugar de .dayOfMonth().withMinimumValue().withDayOfMonth(1)

EDIT:

esto le dará 12/1/YYYY 00:00 y 12/31/YYYY 00:00. Si prefiere que el último del mes sea realmente el primero del mes siguiente (porque está haciendo una cláusula between), elimine el minusDays(1) del cálculo LastOfMonth

+0

Eso es incorrecto para lastOfMonth. –

+0

@Xylian Supongo que depende de la interpretación de la pregunta. Para cualquier día, le dará la medianoche del primer día del mes y la medianoche del último día del mes. Si desea la medianoche del primer día del mes siguiente, simplemente elimine los ".minusDays (1) del segundo. Si aún cree que mi respuesta es incorrecta, por favor amplíe, porque mis pruebas unitarias dicen que funciona. – JustinKSU

Cuestiones relacionadas