Как я могу увеличить дату на один день в Java?

562

Я работаю с датой в таком формате: yyyy-mm-dd.

Как я могу увеличить эту дату на один день?

user48094
источник
10
Если вы используете Java 8 или новее, вы можете использовать новый API даты / времени. Смотрите этот ответ: stackoverflow.com/a/23910924/1115554
micha
4
новый DateTime (). plusDays (1) .toDate () ???
Пьетро

Ответы:

686

Нечто подобное должно сработать:

String dt = "2008-01-01";  // Start date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.setTime(sdf.parse(dt));
c.add(Calendar.DATE, 1);  // number of days to add
dt = sdf.format(c.getTime());  // dt is now the new date
Дейв
источник
50
@Esko, c.roll (Calendar.DATE, true) не катит месяц в последний день месяца.
Сэм Хаслер
18
@ Аммар, это плохая идея, если ты ничего не понял
Никколо М.
13
Я процитирую некоторые JavaDocs ... Calendar.DATE: "... Это синоним DAY_OF_MONTH." Я хотел бы, чтобы JavaDocs разъяснил, что это увеличит большие поля (например, месяц и год). Calendar.roll «Добавляет или вычитает (увеличивает / уменьшает) одну единицу времени в заданном временном поле без изменения больших полей». Опять же, «большие поля» расплывчаты, но это похоже на комментарий Сэма. Я хотел бы, чтобы был StackOverflow для исправления старых JavaDocs.
jcalfee314
4
ребята, к сожалению, совершенно бесполезно добавлять дни, используя DATE, DAY_OF_MONTH или даже DAY_OF_YEAR - все они увеличиваются по модулю. Таким образом, с учетом Календаря 31-12-1970, add (DAY_OF_YEAR, 1) или roll (), однако roll (), наконец, вызывает add (), даст 01-01-1970. Я думаю, что единственный правильный способ - установить время с миллисекундами. Что касается меня, я никогда больше не использую класс Calendar.
Дмитрий Грязин
14
@Bagzerg: Вы не правы . add()накатит дату. Смотри на идеоне .
Жан Хоминал
212

Похоже, что Java значительно отстает от восьми шаров по сравнению с C #. Этот служебный метод показывает способ сделать в Java SE 6 с помощью метода Calendar.add (предположительно, единственный простой способ).

public class DateUtil
{
    public static Date addDays(Date date, int days)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, days); //minus number would decrement the days
        return cal.getTime();
    }
}

Чтобы добавить один день, в соответствии с заданным вопросом, назовите его следующим образом:

String sourceDate = "2012-02-29";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date myDate = format.parse(sourceDate);
myDate = DateUtil.addDays(myDate, 1);
Лиза
источник
4
К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .
Базилик Бурк
80

java.time

В Java 8 и более поздних версиях пакет java.time делает это в значительной степени автоматически. ( Учебник )

Предполагая Stringввод и вывод:

import java.time.LocalDate;

public class DateIncrementer {
  static public String addOneDay(String date) {
    return LocalDate.parse(date).plusDays(1).toString();
  }
}
Даниэль С. Собрал
источник
3
К вашему сведению, как ZonedDateDateTimeи так и OffsetDateTimeесть plusDaysи minusDaysметоды, а такжеLocalDate
Василий Бурк
@BasilBourque Конечно, но информация, доступная в вопросе, принадлежит LocalDate.
Даниэль С. Собрал
2
@DanielCSobral Да. Просто добавив ссылки для назидания ваших читателей. Не критика.
Василий Бурк
65

Я предпочитаю использовать DateUtils от Apache. Проверьте это http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html . Это удобно, особенно когда вам нужно использовать его в нескольких местах в вашем проекте, и вы не хотите писать для этого свой метод с одним вкладышем.

API говорит:

addDays (Date date, int amount): Добавляет количество дней к дате, возвращая новый объект.

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

Рисав Карна
источник
59
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
Calendar cal = Calendar.getInstance();
cal.setTime( dateFormat.parse( inputString ) );
cal.add( Calendar.DATE, 1 );
Алекс Б
источник
48

Создайте объект Calendar и используйте метод add (Calendar.DATE, 1);

krosenvold
источник
43

Посмотрите на Joda-Time ( https://www.joda.org/joda-time/ ).

DateTimeFormatter parser = ISODateTimeFormat.date();

DateTime date = parser.parseDateTime(dateString);

String nextDay = parser.print(date.plusDays(1));
Вилли аус Рор
источник
3
Вы можете удалить вызовы парсера для построения DateTime. Использовать DateTime date = новый DateTime (dateString); Затем nextDay - это ISODateTimeFormat.date (). Print (date.plusDays (1)); См. Joda-time.sourceforge.net/api-release/org/joda/time/… для получения дополнительной информации.
MetroidFan2002
Более подробный пример кода с использованием Joda-Time см. В моем ответе на похожий вопрос: как добавить один день к дате? ,
Базилик Бурк
2
К вашему сведению ... Проект Joda-Time сейчас находится в режиме обслуживания и рекомендует перейти на классы java.time . Оба усилия были во главе с одним и тем же человеком, Стивеном Коулборном. Таким образом, они разделяют схожие концепции, и миграция не является сложной.
Василий Бурк
40

Обратите внимание, что эта строка добавляет 24 часа:

d1.getTime() + 1 * 24 * 60 * 60 * 1000

но эта строка добавляет один день

cal.add( Calendar.DATE, 1 );

В дни с переходом на летнее время (25 или 23 часа) вы получите разные результаты!

Флориан Р.
источник
40

В Java 8 добавлен новый API для работы с датами и временем.

С Java 8 вы можете использовать следующие строки кода:

// parse date from yyyy-mm-dd pattern
LocalDate januaryFirst = LocalDate.parse("2014-01-01");

// add one day
LocalDate januarySecond = januaryFirst.plusDays(1);
Миха
источник
1
Я думаю, вы имели в виду januaryFirst.plusDays(1)нет date.plusDays(1).
TeWu
Это поддерживается только на Android O developer.android.com/reference/java/time/package-summary.html
Subho
1
@Subho Для Android до 26, см. Проект ThreeTenABP, который адаптирует проект ThreeTen-Backport , бэк-порт, если большая часть функциональности java-времени, к Java 6 и Java 7.
Базиль Бурк
29

Вы можете использовать Simple java.util lib

Calendar cal = Calendar.getInstance(); 
cal.setTime(yourDate); 
cal.add(Calendar.DATE, 1);
yourDate = cal.getTime();
Паван Парик
источник
1
Этот Ответ дублирует содержание нескольких Ответов, включая принятый Ответ, полученный три года назад. Пожалуйста, удалите свой ответ или измените, чтобы добавить значение.
Василий Бурк
3
этот ответ чище, не разбирает дату посередине. «принятый ответ» слишком запутанный. хорошо, что вы добавили свое, не обращая внимания на автоматическое замечание
Микки
К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .
Базилик Бурк
Лучший ответ, прямо к делу. Я согласен с Микки, просто не
обращайте
23
Date today = new Date();               
SimpleDateFormat formattedDate = new SimpleDateFormat("yyyyMMdd");            
Calendar c = Calendar.getInstance();        
c.add(Calendar.DATE, 1);  // number of days to add      
String tomorrow = (String)(formattedDate.format(c.getTime()));
System.out.println("Tomorrows date is " + tomorrow);

Это даст завтрашнюю дату. c.add(...)параметры могут быть изменены с 1 на другое число для соответствующего приращения.

Ахилеш Т.
источник
1
Вы можете сделать что-то вроде c.setTime (объект Date), чтобы установить конкретную дату перед добавлением.
Линь Лино
Я бы хотел, чтобы стандартные java-пакеты делали обработку дат менее запутанной ... Я имею в виду, что каждый раз, когда вы хотите иметь дело с датами, это такая боль ... просто напыщенная речь ...
Shn_Android_Dev
1
@Shn_Android_Dev Классы java.time, встроенные в Java 8 и более поздние версии, вытесняют ужасные старые классы даты и времени и отвечают вашему желанию. Также перенесен на Java 6/7 и более ранние версии Android в ThreeTen-Backport Backport и ThreeTenABP . Не нужно когда-либо использовать Dateили Calendarснова.
Василий Бурк
19

Если вы используете Java 8 , то делайте это так.

LocalDate sourceDate = LocalDate.of(2017, Month.MAY, 27);  // Source Date
LocalDate destDate = sourceDate.plusDays(1); // Adding a day to source date.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // Setting date format

String destDate = destDate.format(formatter));  // End date

Если вы хотите использовать SimpleDateFormat , сделайте это следующим образом.

String sourceDate = "2017-05-27";  // Start date

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

Calendar calendar = Calendar.getInstance();
calendar.setTime(sdf.parse(sourceDate)); // parsed date and setting to calendar

calendar.add(Calendar.DATE, 1);  // number of days to add
String destDate = sdf.format(calendar.getTime());  // End date
Авиджит Кармакар
источник
Нет, Вопрос задан для значения только для даты, а не для даты-времени. Так что пользуйся LocalDateклассом нет LocalDateTime.
Василий Бурк
1
Ваш ответ повторяет содержание как минимум четырех других ответов. Пожалуйста, объясните, как ваша добавленная стоимость превышает эти, или удалите, прежде чем собирать отрицательные голоса.
Василий Бурк
16
long timeadj = 24*60*60*1000;
Date newDate = new Date (oldDate.getTime ()+timeadj);

Это берет количество миллисекунд с начала эпохи из oldDate и добавляет миллисекунды за 1 день, а затем использует открытый конструктор Date () для создания даты с использованием нового значения. Этот метод позволяет добавить 1 день или любое количество часов / минут, а не только целые дни.

dvaey
источник
Это, вероятно, не то, что хотел ОП; он не учитывает корректировки типа перехода на летнее время, дополнительные секунды и т. д.
mrec
1
Переход на летнее время должен осуществляться с помощью часового пояса / региона. Мой пример показывал, как увеличивать на небольшие промежутки времени. При увеличении по дням високосные секунды могут быть проблемой, но при добавлении часов это менее вероятно, хотя все еще возможно.
Два
15

Начиная с Java 1.5 TimeUnit.DAYS.toMillis (1) выглядит более понятным для меня.

SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
Date day = dateFormat.parse(string);
// add the day
Date dayAfter = new Date(day.getTime() + TimeUnit.DAYS.toMillis(1));
Jens
источник
Это создает значение даты и времени, когда Вопрос запрашивает только дату. Я предлагаю гораздо более разумный подход - LocalDateкласс в классах java.time для Java 8 и более поздних версий, а также обратный порт для Java 6 и Java 7, обнаруженный в проекте ThreeTen-Backport .
Василий Бурк
14

В Java 8 простой способ сделать это:

Date.from(Instant.now().plusSeconds(SECONDS_PER_DAY))
ДПК
источник
14
Кажется немного натяжкой. Почему бы просто не пойти с Instant.now().plus( 1 , ChronoUnit.DAYS )?
Василий Бурк
Спасибо @BasilBourque
дпк
12

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

Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime());// print today's date
calendar.add(Calendar.DATE, 1);

Теперь установите эту дату на один день вперед с помощью метода calendar.add, который принимает (константа, значение). Здесь константа может быть ДАТА, часы, минуты, секунды и т. Д., А значение - это значение константы. Как и на один день, константа впереди - Calendar.DATE, а ее значение равно 1, потому что мы хотим получить значение на один день вперед.

System.out.println(calendar.getTime());// print modified date which is завтрашнее свидание

Спасибо

Kushwaha
источник
11

В Java 8 вы можете использовать java.time.LocalDate

LocalDate parsedDate = LocalDate.parse("2015-10-30"); //Parse date from String
LocalDate addedDate = parsedDate.plusDays(1);   //Add one to the day field

Вы можете преобразовать в java.util.Dateобъект следующим образом.

Date date = Date.from(addedDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Вы можете LocalDateпреобразовать в строку следующим образом.

String str = addedDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
Рамеш-X
источник
7

Просто укажите дату в строке и количество следующих дней

 private String getNextDate(String givenDate,int noOfDays) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        String nextDaysDate = null;
    try {
        cal.setTime(dateFormat.parse(givenDate));
        cal.add(Calendar.DATE, noOfDays);

       nextDaysDate = dateFormat.format(cal.getTime());

    } catch (ParseException ex) {
        Logger.getLogger(GR_TravelRepublic.class.getName()).log(Level.SEVERE, null, ex);
    }finally{
    dateFormat = null;
    cal = null;
    }

    return nextDaysDate;

}
ЛМК
источник
7

Если вы хотите добавить одну единицу времени и ожидаете увеличения других полей, вы можете смело использовать метод add. Смотрите пример ниже:

SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.set(1970,Calendar.DECEMBER,31);
System.out.println(simpleDateFormat1.format(cal.getTime()));
cal.add(Calendar.DATE, 1);
System.out.println(simpleDateFormat1.format(cal.getTime()));
cal.add(Calendar.DATE, -1);
System.out.println(simpleDateFormat1.format(cal.getTime()));

Напечатает:

1970-12-31
1971-01-01
1970-12-31
terrmith
источник
Нет принятого ответа, и я чувствовал, что возникла путаница, если другие поля также обновляются.
Термит
7
startCalendar.add(Calendar.DATE, 1); //Add 1 Day to the current Calender
Абдурахман Попал
источник
4
Спасибо за желание внести свой вклад. Однако это уже есть в нескольких других ответах, так что я действительно не вижу смысла… Кроме этого ИМХО, никто не должен использовать плохо спроектированный и давно устаревший Calendarкласс в 2019 году.
Оле В.В.
6

Если вы используете Java SE 8 или выше, вы должны использовать новый API Date / Time

 int days = 7;       
 LocalDate dateRedeemed = LocalDate.now();
 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/YYYY");

 String newDate = dateRedeemed.plusDays(days).format(formatter);   
 System.out.println(newDate);

Если вы должны конвертировать из java.util.Dateв java.time.LocalDate, вы можете использовать этот метод.

  public LocalDate asLocalDate(Date date) {
      Instant instant = date.toInstant();
      ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
      return zdt.toLocalDate();
  }

Если вы используете версию до Java SE 8, я советую вам использовать Joda-Time

Joda-Time обеспечивает качественную замену для классов даты и времени Java и является де-факто стандартной библиотекой даты и времени для Java до Java SE 8

   int days = 7;       
   DateTime dateRedeemed = DateTime.now();
   DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/uuuu");

   String newDate = dateRedeemed.plusDays(days).toString(formatter);   
   System.out.println(newDate);
Эдуардо Эляйек
источник
1
Ваш шаблон для java.timeчасти неверен. Это должно быть dd/MM/uuuuэквивалентно JodaTime.
TiiJ7
5

Используйте DateFormatAPI для преобразования String в объект Date, затем используйте CalendarAPI для добавления одного дня. Дайте мне знать, если вы хотите конкретные примеры кода, и я могу обновить свой ответ.

Росс
источник
3

Если вы используете Java 8, java.time.LocalDateи java.time.format.DateTimeFormatterможете сделать эту работу довольно простой.

public String nextDate(String date){
      LocalDate parsedDate = LocalDate.parse(date);
      LocalDate addedDate = parsedDate.plusDays(1);
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-mm-dd");
      return addedDate.format(formatter); 
}
Эван Ху
источник
Еще проще: отбросьте модуль форматирования и просто используйте его toString()для создания формата string i yyyy-MM-dd (и, если вы настаиваете, помните, что mmэто минуты, а MMмесяц).
Оле В.В.
3

Вы можете использовать этот пакет из "org.apache.commons.lang3.time":

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 Date myNewDate = DateUtils.addDays(myDate, 4);
 Date yesterday = DateUtils.addDays(myDate, -1);
 String formatedDate = sdf.format(myNewDate);  
Шахид
источник
5
Предлагать Dateзанятия в 2018 году - плохой совет. Мучительные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь являются устаревшими , вытесняются классами java.time, встроенными в Java 8 и Java 9. См. Учебное пособие Oracle . Смотрите другие ответы, используя LocalDateкласс.
Василий Бурк
Да, это лучший способ сделать LocalDate,
Шахид,
однако некоторые фреймворки, такие как jsf, имеют небольшие проблемы интеграции с API времени, поэтому иногда вам следует использовать Date; плюс среда Ява <8
Удача
1
@Lucke Большая часть функциональности java.time была перенесена на Java 6 & 7 в проекте ThreeTen-Backport . Далее адаптирован под более старый Android в проекте ThreeTenABP . Так что, действительно, не нужно когда-либо трогать эти кровавые ужасные старые классы даты и времени. Многие фреймворки были обновлены. Но не все. Поэтому, если вам необходимо взаимодействовать со старым кодом, который еще не обновлен до java.time , напишите свой новый код в java.time и выполните преобразование в / из старых типов, вызвав новые методы преобразования, добавленные в старые классы.
Василий Бурк
1
Этот код игнорирует критическую проблему часового пояса . В любой конкретный момент дата варьируется в зависимости от зоны. К SimpleDateFormatсожалению, класс вводит часовой пояс, неявно применяя текущую зону по умолчанию JVM. Таким образом, результаты этого кода будут отличаться в зависимости от текущего значения по умолчанию - и это значение по умолчанию может измениться в любой момент во время выполнения.
Василий Бурк
3

Это на самом деле просто. Один день содержит 86400000 миллисекунд. Итак, сначала вы получите текущее время в миллисекундах из системы, используя System.currentTimeMillis()затем добавьте 84000000 миллисекунд и используйтеDate класс для генерации формата даты в миллисекундах.

пример

String Today = new Date(System.currentTimeMillis()).toString();

Строка Сегодня будет 2019-05-9

String Tommorow = new Date(System.currentTimeMillis() + 86400000).toString();

Струна завтра будет 2019-05-10

String DayAfterTommorow = new Date(System.currentTimeMillis() + (2 * 86400000)).toString();

Строка DayAfterTommorow будет 2019-05-11

Майк Т
источник
Этот код использует ужасный Dateкласс, который был вытеснен много лет назад современными классами java.time . Намного проще просто:LocalDate.parse( "2019-01-23" ).plusDays( 1 )
Василий Бурк
2

Давайте проясним пример использования: вы хотите сделать арифметику календаря и начать / закончить с java.util.Date .

Некоторые подходы:

  1. Преобразование в строку и обратно с SimpleDateFormat : это неэффективное решение.
  2. Конвертировать в LocalDate : вы потеряете любую информацию о времени суток.
  3. Преобразовать в LocalDateTime : это включает в себя больше шагов, и вам нужно беспокоиться о часовом поясе.
  4. Преобразовать в эпоху с Date.getTime () : это эффективно, но вы рассчитываете с миллисекундами.

Рассмотрите возможность использования java.time.Instant :

Date _now = new Date();
Instant _instant = _now.toInstant().minus(5, ChronoUnit.DAYS);
Date _newDate = Date.from(_instant);
Чад Джулиано
источник
1
Никогда не смешивайте ужасные унаследованные классы, такие как Dateсовременные классы java.time, такие как Instant. В java.time классы полностью вытеснять устаревшие классы. Конкретно Instantзаменяет java.util.Date.
Василий Бурк
1
Не затрагивает вопрос. Вы используете классы, представляющие момент (дату с временем суток в контексте смещения или зоны). Но Вопрос касается только даты без времени суток и без часового пояса. Смотрите правильный ответ от Собрала и правильный ответ от Миха.
Базилик Бурк
0
Date newDate = new Date();
newDate.setDate(newDate.getDate()+1);
System.out.println(newDate);
Филип Трайцевский
источник
14
к сведению, Date.setDate () устарела
Келли С. Френч
На моем компьютере, кажется, работает через границу месяца. После Sun Apr 30 16:25:33 CEST 2017приходит Mon May 01 16:25:33 CEST 2017. Это все еще обескураженное решение. Мало того, что метод устарел по уважительной причине, также в 2017 году у нас есть очень хорошие альтернативы Dateклассу.
Оле В.В.