web-dev-qa-db-fra.com

Premier jour du mois prochain avec Java Joda-Time

Comment réécririez-vous la méthode ci-dessous, qui renvoie le premier jour du mois suivant, avec le org.joda.time package dans Joda-Time ?

public static Date firstDayOfNextMonth() {
    Calendar nowCal = Calendar.getInstance();
    int month = nowCal.get(Calendar.MONTH) + 1;
    int year = nowCal.get(Calendar.YEAR);

    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    Date dueDate = new Date(cal.getTimeInMillis());

    return dueDate;
}
40
Mat B.
   LocalDate today = new LocalDate();
   LocalDate d1 = today.plusMonths(1).withDayOfMonth(1);

Un peu plus facile et plus propre, non? :-)

Mise à jour: Si vous souhaitez renvoyer une date:

return new Date(d1.toDateTimeAtStartOfDay().getMillis());

mais je vous conseille fortement d'éviter de mélanger des types DATE purs (c'est-à-dire un jour dans le calendrier, sans informations d'heure) avec des types DATETIME, spécialement avec un type datetime "physique" comme c'est le hideux Java.util.Date. C'est un peu comme convertir des types entiers en nombres entiers et flottants, vous devez être prudent.

45
leonbloy

Je suppose que vous souhaitez renvoyer un objet Date, donc:

public static Date firstDayOfNextMonth() {
    MutableDateTime mdt = new MutableDateTime();
    mdt.addMonths(1);
    mdt.setDayOfMonth(1);
    mdt.setMillisOfDay(0); // if you want to make sure you're at midnight
    return mdt.toDate();
}
21
delfuego

Joda-Time

Voici mon point de vue sur ce problème, en utilisant Joda-Time 2.3.

Immuable

En règle générale, vous devez utiliser les versions immuable des classes Joda-Time. Presque toutes les méthodes renvoient une nouvelle instance de DateTime plutôt que de modifier une instance existante. Simplifie les choses et permet une sécurité automatique des threads.

Début de journée

Utilisez la méthode la plus récente withTimeAtStartOfDay() plutôt que de régler l'heure du jour à zéro. En raison de l'heure d'été (DST) et d'autres anomalies, certains jours dans certains fuseaux horaires, il n'y a pas de minuit ou de minuit.

Convertir: j.u.Date ↔ DateTime

Pour traduire une instance Joda-Time DateTime en une instance Java.util.Date , il suffit d'appeler la méthode toDate . Pas besoin de constructeur à la date.

Dans l'autre sens, si vous avez un Java.util.Date et que vous voulez un Joda-Time DateTime, transmettez simplement la Date au constructeur de DateTime avec l'objet DateTimeZone souhaité.

Exemple de code

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
// Usually better to specify a time zone rather than rely on default.
DateTime now = new DateTime( timeZone ); // Or, for default time zone: new DateTime()
DateTime monthFromNow = now.plusMonths(1);
DateTime firstOfNextMonth = monthFromNow.dayOfMonth().withMinimumValue();
DateTime firstMomentOfFirstOfNextMonth = firstOfNextMonth.withTimeAtStartOfDay();

Ou, si vous êtes un maniaque, enchaînez tout cela dans une seule ligne de code.

DateTime allInOneLine = new DateTime( DateTimeZone.forID( "Europe/Paris" ) ).plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();

Traduire en un ancien Java.util.Date pour l'interaction avec d'autres classes/bibliothèques.

Java.util.Date date = firstMomentOfFirstOfNextMonth.toDate();

Dump sur console…

System.out.println( "now: " + now );
System.out.println( "monthFromNow: " + monthFromNow );
System.out.println( "firstOfNextMonth: " + firstOfNextMonth );
System.out.println( "firstMomentOfFirstOfNextMonth: " + firstMomentOfFirstOfNextMonth );
System.out.println( "allInOneLine: " + allInOneLine );
System.out.println( "date: " + date );

Lors de l'exécution ...

now: 2014-01-21T02:46:16.834+01:00
monthFromNow: 2014-02-21T02:46:16.834+01:00
firstOfNextMonth: 2014-02-01T02:46:16.834+01:00
firstMomentOfFirstOfNextMonth: 2014-02-01T00:00:00.000+01:00
allInOneLine: 2014-02-01T00:00:00.000+01:00
date: Fri Jan 31 15:00:00 PST 2014

Java.time

Le cadre Java.time intégré à Java 8 et versions ultérieures remplace les anciennes classes Java.util.Date/.Calendar. Inspiré de Joda-Time et destiné à être son successeur.

Ces nouvelles classes incluent l'interface TemporalAdjuster ( Tutorial ) avec un tas d'implémentations dans TemporalAdjusters (notez le pluriel s). Arrive d'avoir juste le réglage dont nous avons besoin: firstDayOfNextMonth .

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
LocalDate firstOfNextMonth = today.with ( TemporalAdjusters.firstDayOfNextMonth () );

Dump sur console.

System.out.println ( "today: " + today + "  |  firstOfNextMonth: " + firstOfNextMonth );

aujourd'hui: 22/12/2015 | firstOfNextMonth: 2016-01-01

Si vous souhaitez une date-heure plutôt qu'une date uniquement, ajustez.

ZonedDateTime zdt = firstOfNextMonth.atStartOfDay( zoneId );

Si vous devez utiliser l'ancien Java.util.Date pour fonctionner avec d'anciennes classes non encore mises à jour vers Java.time, convertissez à partir d'un Instant extrait de l'objet ZonedDateTime. Un instantané est un moment sur la timeline en UTC.

Java.util.Date date = Java.util.Date.from( zdt.toInstant() );

À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien hérité classes date-heure telles que Java.util.Date , Calendar , & SimpleDateFormat .

Le projet Joda-Time , maintenant en mode maintenance , conseille la migration vers Java.time = classes.

Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 31 .

Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.* Des classes.

Où obtenir les classes Java.time?

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à Java.time. Vous pouvez trouver ici des classes utiles telles que Interval , YearWeek , YearQuarter , et plus .

15
Basil Bourque

il existe une méthode pour cela dans l'API Joda:

Date date = new LocalDate().plusMonths(1).dayOfMonth().withMinimumValue().toDate();

J'espère que cela aide!

6
avaz

le même qu'avant mais converti également en Java.util.Date

Date firstDayOfNextMonth = (new LocalDate (). PlusMonths (1) .withDayOfMonth (1)). ToDate ();

2
simonC

localDate = new LocalDate (). plusMonths (1) .withDayOfMonth (1);

1
Tomasz Krzyżak

je ne sais pas si "je" ai la bonne question, mais voici mon essai: D .. comme n'ajoute pas le +1 mois ???

public static Date firstDayOfNextMonth() {
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();  

        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 1);

        Date dueDate = new Date(cal.getTimeInMillis());

    return dueDate;
}
0
BaajiRao