web-dev-qa-db-fra.com

Dans Joda-Time, définissez DateTime sur le début du mois

Mon API permet au client de la bibliothèque de passer Date:

method(Java.util.Date date)

Travailler avec Joda-Time , à partir de cette date, je voudrais extraire le mois et le parcourir tous les jours de ce mois.

Maintenant, la date passée est généralement new Date () - signifiant instant actuel. Mon problème est en fait de définir la nouvelle instance DateMidnight (jdkDate) pour être au début du mois.

Quelqu'un pourrait-il s'il vous plaît démontrer ce cas d'utilisation avec Joda-Time ?

29
Maxim Veksler

Minuit au début du premier jour du mois en cours est donné par:

// first midnight in this month
DateMidnight first = new DateMidnight().withDayOfMonth(1);

// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);

Si vous démarrez à partir d'un fichier Java.util.Date, un autre constructeur DateMidnight est utilisé: 

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

Document Java sur Joda Time - https://www.joda.org/joda-time/apidocs/overview-summary.html

43
Lachlan Roche

Une autre façon (sans prendre en compte DateMidnight) d’obtenir le premier jour du mois serait d’utiliser: 

  DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
31
ngeek

Premier moment du jour

La réponse de de ngeek est correcte, mais ne permet pas d'indiquer l'heure au premier moment de la journée. Pour régler l'heure, ajoutez un appel à 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 );

Lorsqu'il est exécuté à Seattle aux États-Unis…

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

Notez la différence entre ces deux lignes de sortie de la console: -7 vs -8 en raison de heure d'été .


En règle générale, vous devez toujours spécifier le fuseau horaire plutôt que de vous fier à la valeur par défaut. Omis ici pour plus de simplicité. Vous devez ajouter une ligne comme celle-ci et passer l'objet de fuseau horaire aux constructeurs utilisés dans l'exemple ci-dessus.

// 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

Ce qui précède est correct mais obsolète. La bibliothèque Joda-Time est maintenant remplacée par le framework Java.time intégré à Java 8 et versions ultérieures. 

LocalDate représente une valeur de date uniquement sans heure et sans fuseau horaire. Un fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie selon les zones du globe.

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

Utilisez l’une des TemporalAdjusters pour obtenir le premier du mois.

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

La LocalDate peut générer une ZonedDateTime qui représente le premier moment de la journée.

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
8
Basil Bourque

Oh, je n'ai pas vu qu'il s'agissait de jodatime. En tous cas:

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());
}

Ou en utilisant 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);
}

5
andi5

DateMidnight est maintenant obsolète. Au lieu de cela, vous pouvez faire:

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

Si vous connaissez le fuseau horaire, utilisez plutôt new LocalDate(date, timeZone) pour une plus grande précision.

Vous pouvez aussi faire .dayOfMonth().withMinimumValue() au lieu de .withDayOfMonth(1)

MODIFIER:

Cela vous donnera 12/1/YYYY 00:00 et 12/31/YYYY 00:00. Si vous préférez que le dernier du mois soit réellement le premier du mois suivant (car vous faites une clause entre les deux), supprimez la minusDays(1) du dernier calcul

0
JustinKSU