Как вычесть X дней из даты, используя календарь Java? - PullRequest
166 голосов
/ 17 октября 2008

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

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

Ответы [ 9 ]

285 голосов
/ 17 октября 2008

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

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

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).
38 голосов
/ 17 октября 2008

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

35 голосов
/ 17 октября 2008

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

К вашему сведению в Джода Тайм вы можете сделать

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
11 голосов
/ 04 ноября 2015

ТЛ; др

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

О 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?

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

5 голосов
/ 13 августа 2012

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

API говорит:

addDays(Date date, int amount)

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

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

5 голосов
/ 17 октября 2008
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)

1 голос
/ 19 декабря 2017

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

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 голос
/ 28 октября 2011

Кто-то рекомендовал Joda Time так - я использовал это CalendarDate class 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
}
0 голосов
/ 25 сентября 2009

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

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