Как вычесть X дней из даты с помощью Java calendar?


кто-нибудь знает простой способ с помощью Java calendar вычесть X дней из даты?

Я не смог найти ни одной функции, которая позволяет мне напрямую вычитать X дней из даты в Java. Может кто-нибудь указать мне правильное направление?

9 158

9 ответов:

принято от документы здесь:

добавляет или вычитает указанное количество времени в данное поле календаря, основываясь на правилах календаря. Например, чтобы вычесть 5 дней из текущего времени календаря, вы можете добиться этого, позвонив:

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

вы могли бы использовать add метод и передать ему отрицательное число. Однако, вы также можете написать простой метод, который не использует Calendar класс, такой как следующий

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

это возвращает значение timestamp даты (в миллисекундах с начала эпохи) и добавляет нужное количество миллисекунд. Вы можете передать отрицательное целое число для параметра days, чтобы выполнить вычитание. Это было бы проще, чем "правильное" решение календаря:

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

обратите внимание, что оба эти решения меняют Date объект передается как параметр, а не возвращает совершенно новый Date. Любая функция может быть легко изменена, чтобы сделать это в другую сторону, если это необходимо.

Энсон будет работать нормально для простого случая, но если вы собираетесь сделать какие-либо более сложные вычисления даты я бы рекомендовал проверить Джода Времени. Это сделает вашу жизнь намного проще.

FYI в Джода время вы могли бы сделать

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);

tl; dr

LocalDate.now().minusDays( 10 )

лучше указать часовой пояс.

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

подробности

старые классы даты и времени в комплекте с ранними версиями Java, например java.util.Date/.Calendar, было доказано, чтобы быть хлопотно, запутанным, и недостатки. Избегать их.

java.время

Java 8 и позже заменяет эти старые классы с новой java.временные рамки. Смотрите учебник. Определяется JSR 310, вдохновленные Joda Времени и продлен ThreeTen-Extra. Проект ThreeTen-Backport back-переносит классы на Java 6 & 7; проект ThreeTenABP на Android.

вопрос расплывчатый, неясный, если он запрашивает только дату или дату-время.

LocalDate

только для даты, без времени суток, используйте LocalDate класса. Обратите внимание, что часовой пояс имеет решающее значение при определении даты, такой как "сегодняшний день."

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

ZonedDateTime

если вы имели в виду дату-время, то используйте Instant класса, чтобы получить момент на временной шкале в UTC. Оттуда, приспособиться к часовому поясу, чтобы получить ZonedDateTime, теперь режим обслуживания, советует миграцию в java.время классы.

чтобы узнать больше, смотрите Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация это JSR 310.

вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте - драйвера соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в java.sql.* классы.

где получить java.время занятий?

  • Java SE 8, Java SE 9, Java SE 10, и позже
    • встроенный.
    • часть стандартного Java API с комплектной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • большая часть java.функциональность время портированы с Java 6 и 7 в ThreeTen-Backport.
  • Android
    • более поздние версии Android bundle реализации java.время занятий.
    • для более ранних Android ( ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). Смотрите как использовать ThreeTenABP....

The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как Interval,YearWeek,YearQuarter и больше.

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

edit: синтаксическому анализатору, похоже, не нравится Ссылка на Javadoc, поэтому здесь она находится в открытом тексте:

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

вместо того, чтобы писать свою собственную addDays Как предложил Эли, я бы предпочел использовать DateUtils С Apache. Это удобно, особенно когда вы должны использовать его несколько мест в вашем проекте.

API говорит:

addDays(Date date, int amount)

добавляет число дней к дате возврата нового объекта.

обратите внимание, что он возвращает новый Date объект и не вносит изменений в предыдущий сам.

кто - то рекомендовал Joda Time so-я использую это CalendarDate класс http://calendardate.sourceforge.net

это несколько конкурирующий проект для Joda Time, но гораздо более простой только в 2 классах. Это очень удобно и то, что мне нужно, так как я не хочу использовать пакет больше, чем мой проект. В отличие от аналогов Java, его наименьшая единица-это день, поэтому это действительно дата (не имея ее до миллисекунд или нечто.) После того, как вы создадите дату, все, что вы делаете, чтобы вычесть что-то вроде myDay.addDays (-5), чтобы вернуться на 5 дней. Вы можете использовать его, чтобы найти день недели и тому подобное. Другой пример:

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

и:

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

Eli Courtwright второе решение неверно, оно должно быть:

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

Это можно легко сделать следующим

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