Как вычесть X дней с даты с помощью Java-календаря?

Кто-нибудь знает простой способ использования Java-календаря для вычитания X дней с даты?

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

Ответ 1

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

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

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

Ответ 2

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

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

Получает значение отметки времени (миллисекунды с эпохи) и добавляет правильное количество миллисекунд. Вы можете передать отрицательное целое число для параметра 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. Любая функция может быть легко изменена, чтобы сделать это другим способом, если это необходимо.

Ответ 3

Ответ Anson будет отлично работать для простого случая, но если вы собираетесь делать более сложные вычисления даты, я бы рекомендовал проверить Joda Time. Это облегчит вашу жизнь.

FYI в Йоде Время, которое вы могли бы сделать

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

Ответ 4

ТЛ; др

LocalDate.now().minusDays( 10 )

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

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

подробности

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

java.time

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

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

LocalDate

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

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

ZonedDateTime

Если вы имели в виду дату и время, используйте класс Instant чтобы получить момент времени на UTC. Оттуда установите часовой пояс, чтобы получить объект 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.


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

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

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

Где взять классы java.time?

  • Java SE 8, Java SE 9, Java SE 10 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….

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

Ответ 6

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

API говорит:

addDays(Date date, int amount)

Добавляет несколько дней к дате, возвращающей новый объект.

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

Ответ 7

Кто-то рекомендовал время Joda так - я использовал этот 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
}

Ответ 8

Это легко сделать следующим образом:

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

Ответ 9

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

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