web-dev-qa-db-fra.com

Comment soustraire X jours à une date à l'aide de Java calendar?

Quelqu'un connaît-il un moyen simple d'utiliser Java calendar pour soustraire X jours à une date?

Je n'ai pu trouver aucune fonction qui me permette de soustraire directement X jours d'une date en Java. Est-ce que quelqu'un peut me diriger dans la bonne direction?

168
fmsf

Tiré de les docs ici :

Ajoute ou soustrait la durée spécifiée au champ de calendrier donné, en fonction des règles du calendrier. Par exemple, pour soustraire 5 jours à l'heure actuelle du calendrier, vous pouvez le réaliser en appelant:

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).
291
Anson Smith

Vous pouvez utiliser la méthode add et lui donner un nombre négatif. Cependant, vous pouvez aussi écrire une méthode plus simple qui n’utilise pas la classe Calendar telle que la suivante

public static void addDays(Date d, int days)
{
    d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}

Cela obtient la valeur d'horodatage de la date (millisecondes depuis l'époque) et ajoute le nombre approprié de millisecondes. Vous pouvez passer un entier négatif pour que le paramètre days fasse une soustraction. Ce serait plus simple que la solution de calendrier "appropriée":

public static void addDays(Date d, int days)
{
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    c.add(Calendar.DATE, days);
    d.setTime( c.getTime().getTime() );
}

Notez que ces deux solutions modifient l'objet Date passé en tant que paramètre plutôt que de renvoyer un tout nouveau Date. L'une ou l'autre fonction peut être facilement modifiée pour le faire dans l'autre sens si vous le souhaitez.

38
Eli Courtwright

La réponse d'Anson fonctionnera bien pour le cas simple, mais si vous voulez faire des calculs de date plus complexes, je vous conseillerais de vérifier Joda Time . Cela vous facilitera beaucoup la vie.

FYI in Joda Temps que vous pourriez faire

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
35
Mike Deck

tl; dr

_LocalDate.now().minusDays( 10 )
_

Mieux vaut spécifier le fuseau horaire.

_LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
_

Détails

Les anciennes classes date-heure regroupées avec les premières versions de Java, telles que _Java.util.Date_/_.Calendar_, se sont révélées gênantes, confuses et défectueuses. Évite-les.

Java.time

Java 8 et versions ultérieures supplantent ces anciennes classes avec le nouveau framework Java.time. Voir Tutorial . Défini par JSR 310 , inspiré de Joda-Time , et étendu par le projet ThreeTen-Extra . Le projet ThreeTen-Backport transfère les classes vers Java 6 & 7; le projet ThreeTenABP sur Android.

La question est vague, elle ne sait pas si elle demande une date seulement ou une date/heure.

LocalDate

Pour une date uniquement, sans heure, utilisez LocalDate class. Notez qu'un fuseau horaire est crucial pour déterminer une date telle que "aujourd'hui".

_LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
_

ZonedDateTime

Si vous vouliez dire une date-heure, utilisez alors la classe Instant / pour obtenir un instant sur la timeline dans UTC . A partir de là, ajustez-vous sur un fuseau horaire pour obtenir un objet ZonedDateTime .

_Instant now = Instant.now();  // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
_

Table of date-time types in Java, both modern and legacy.


À propos de Java.time

Le cadre Java.time est intégré à partir de Java 8. Ces classes supplantent les anciennes legacy / anciennes classes problématiques telles que Java.util.Date , Calendar , & SimpleDateFormat .

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

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

Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC conforme à JDBC 4.2 ou ultérieur. Pas besoin de chaînes, pas besoin de _Java.sql.*_ classes.

Où obtenir les classes Java.time?

Le ThreeTen-Extra project étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval , YearWeek , YearQuarter , et more .

13
Basil Bourque

Au lieu d'écrire mon propre addDays comme suggéré par Eli, je préférerais utiliser DateUtils de Apache. C'est pratique surtout lorsque vous devez l'utiliser à plusieurs endroits dans votre projet.

L'API dit:

addDays(Date date, int amount)

Ajoute un nombre de jours à une date renvoyant un nouvel objet.

Notez qu'il renvoie un nouvel objet Date et ne modifie pas l'objet précédent.

5
Risav Karna
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);

edit: l'analyseur ne semble pas aimer le lien vers la Javadoc, donc le texte est en clair:

http://Java.Sun.com/j2se/1.4.2/docs/api/Java/util/Calendar.html#add (int , int)

5
matt b

Cela peut être fait facilement par ce qui suit

Calendar calendar = Calendar.getInstance();
        // from current time
        long curTimeInMills = new Date().getTime();
        long timeInMills = curTimeInMills - 5 * (24*60*60*1000);    // `enter code here`subtract like 5 days
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());

        // from specific time like (08 05 2015)
        calendar.set(Calendar.DAY_OF_MONTH, 8);
        calendar.set(Calendar.MONTH, (5-1));
        calendar.set(Calendar.YEAR, 2015);
        timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000);
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());
1
rab

Quelqu'un a recommandé Joda Time donc - j'ai utilisé cette classe CalendarDate http://calendardate.sourceforge.net

C'est un projet un peu concurrent de Joda Time, mais beaucoup plus basique à seulement 2 cours. C'est très pratique et a très bien fonctionné pour ce dont j'avais besoin, car je ne voulais pas utiliser un paquet plus gros que mon projet. Contrairement aux contreparties Java, sa plus petite unité est le jour, donc c'est vraiment une date (ne pas l'avoir en millisecondes ou quelque chose comme ça). Une fois que vous avez créé la date, tout ce que vous faites pour soustraire est quelque chose comme myDay.addDays (-5) pour revenir 5 jours en arrière. Vous pouvez l'utiliser pour trouver le jour de la semaine et des choses comme ça. Un autre exemple:

CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);

Et:

//print 4 previous days of the week and today
String dayLabel = "";
CalendarDate today = new CalendarDate(TimeZone.getDefault());
CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon"
CalendarDate currDay = today.addDays(-4);
while(!currDay.isAfter(today)) {
    dayLabel = cdf.format(currDay);
    if (currDay.equals(today))
        dayLabel = "Today";//print "Today" instead of the weekday name
    System.out.println(dayLabel);
    currDay = currDay.addDays(1);//go to next day
}
1
mikato

La deuxième solution d'Eli Courtwright est fausse, elle devrait être:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
0
user178973