Jak mogę zwiększyć datę o jeden dzień w Javie?

561

Pracuję z datą w formacie: yyyy-mm-dd.

Jak mogę zwiększyć tę datę o jeden dzień?

użytkownik48094
źródło
10
Jeśli używasz Java 8 lub nowszej wersji, możesz użyć nowego interfejsu daty / godziny. Zobacz tę odpowiedź: stackoverflow.com/a/23910924/1115554
micha
4
nowy DateTime (). plusDays (1) .toDate () ???
Pietro

Odpowiedzi:

684

Coś takiego powinno załatwić sprawę:

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
Dave
źródło
50
@Esko, c.roll (Calendar.DATE, true) nie zroluje miesiąca w ostatnim dniu miesiąca.
Sam Hasler,
18
@Ammar to zły pomysł, jeśli nic nie zrozumiałeś
niccolo m.
13
Zacytuję niektóre JavaDocs ... Calendar.DATE: „... To jest synonim DAY_OF_MONTH.” Chciałbym, aby JavaDocs wyjaśnił, że zwiększyłoby to większe pola (jak miesiąc i rok). Calendar.roll „Dodaje lub odejmuje (w górę / w dół) jedną jednostkę czasu w danym polu czasu bez zmiany większych pól”. Ponownie „większe pola” są niejasne, ale wydaje się zgodne z komentarzem Sama. Żałuję, że nie było StackOverflow do naprawy starych JavaDocs.
jcalfee314
4
chłopaki, niestety, bezużyteczne jest dodawanie dni za pomocą DATE, DAY_OF_MONTH, a nawet DAY_OF_YEAR - wszystkie są zwiększane przez moduł. Biorąc pod uwagę Kalendarz z 31-12-1970, dodaj (DAY_OF_YEAR, 1) lub roll (), jednak roll () w końcu wywołuje add (), da 01-01-1970. Chyba jedynym właściwym sposobem jest ustawienie czasu w milisekundach. Co do mnie, nigdy więcej nie używam zajęć z kalendarza.
Dmitry Gryazin
14
@Bagzerg: Mylisz się . add()rzuci datę. Zobacz na ideone .
Jean Hominal
211

Java wydaje się być daleko w tyle za ósemką w porównaniu do C #. Ta metoda narzędzia pokazuje, jak to zrobić w Javie SE 6 za pomocą metody Calendar.add (przypuszczalnie jedyny łatwy sposób).

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

Aby dodać jeden dzień, zgodnie z zadanym pytaniem, nazwij go w następujący sposób:

String sourceDate = "2012-02-29";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date myDate = format.parse(sourceDate);
myDate = DateUtil.addDays(myDate, 1);
Lisa
źródło
4
Do Twojej wiadomości, strasznie kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque,
79

java.time

W Javie 8 i nowszych pakiet java.time sprawia, że ​​jest to prawie automatyczne. ( Samouczek )

Zakładając Stringwejście i wyjście:

import java.time.LocalDate;

public class DateIncrementer {
  static public String addOneDay(String date) {
    return LocalDate.parse(date).plusDays(1).toString();
  }
}
Daniel C. Sobral
źródło
3
Do Twojej wiadomości ZonedDateDateTime a OffsetDateTimetakże plusDaysi minusDaysmetody, a takżeLocalDate
Basil Bourque
@BasilBourque Pewnie, ale informacje dostępne w pytaniu są takie LocalDate.
Daniel C. Sobral
2
@DanielCSobral Yep. Po prostu dodajemy linki do edycji twoich czytelników. Nie krytyka.
Basil Bourque,
65

Wolę używać DateUtils z Apache. Sprawdź to http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html . Jest to przydatne zwłaszcza, gdy musisz użyć go w wielu miejscach w swoim projekcie i nie chciałbyś do tego pisać jednej metody liniowej.

Interfejs API mówi:

addDays (Data, int liczba): Dodaje liczbę dni do daty zwracając nowy obiekt.

Zwróć uwagę, że zwraca nowy obiekt Date i nie wprowadza zmian w samym poprzednim.

Risav Karna
źródło
59
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
Calendar cal = Calendar.getInstance();
cal.setTime( dateFormat.parse( inputString ) );
cal.add( Calendar.DATE, 1 );
Alex B.
źródło
48

Zbuduj obiekt kalendarza i użyj metody add (Calendar.DATE, 1);

krosenvold
źródło
43

Spójrz na Joda-Time ( https://www.joda.org/joda-time/ ).

DateTimeFormatter parser = ISODateTimeFormat.date();

DateTime date = parser.parseDateTime(dateString);

String nextDay = parser.print(date.plusDays(1));
Willi aus Rohr
źródło
3
Można usunąć wywołania analizatora składni w celu utworzenia DateTime. Użyj DateTime date = new DateTime (dateString); Następnie nextDay jest ISODateTimeFormat.date (). Print (date.plusDays (1)); Aby uzyskać więcej informacji, zobacz joda-time.sourceforge.net/api-release/org/joda/time/ ...
MetroidFan2002
Aby uzyskać bardziej szczegółowy przykładowy kod przy użyciu Joda-Time, zobacz moją odpowiedź na podobne pytanie: Jak dodać jeden dzień do daty? .
Basil Bourque,
2
FYI… Projekt Joda-Time jest teraz w trybie konserwacji i zaleca migrację do klas java.time . Oba wysiłki kierował ten sam mężczyzna, Stephen Colebourne. Dlatego mają podobne koncepcje, a migracja nie jest trudna.
Basil Bourque
40

Pamiętaj, że ten wiersz dodaje 24 godziny:

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

ale ta linia dodaje jeden dzień

cal.add( Calendar.DATE, 1 );

W dni ze zmianą czasu letniego (25 lub 23 godzin) otrzymasz różne wyniki!

Florian R.
źródło
40

Java 8 dodała nowy interfejs API do pracy z datami i godzinami.

W Javie 8 możesz użyć następujących wierszy kodu:

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

// add one day
LocalDate januarySecond = januaryFirst.plusDays(1);
Micha
źródło
1
Chyba masz na myśli januaryFirst.plusDays(1)nie date.plusDays(1).
TeWu,
Jest to obsługiwane tylko w
Androidzie
1
@Subho dla Androida przed 26, zobacz ThreeTenABP projekt, który dostosowuje ThreeTen-backportu projektu, back-portowy, jeśli większość java czasu funkcjonalność Java 6 i Java 7.
Basil Bourque
29

możesz użyć Simple java.util lib

Calendar cal = Calendar.getInstance(); 
cal.setTime(yourDate); 
cal.add(Calendar.DATE, 1);
yourDate = cal.getTime();
Pawan Pareek
źródło
1
Niniejsza odpowiedź powiela treść wielu odpowiedzi, w tym odpowiedzi zaakceptowanej sprzed trzech lat. Usuń swoją odpowiedź lub edytuj, aby dodać wartość.
Basil Bourque,
3
ta odpowiedź jest czystsza, nie analizuje daty pośrodku. „zaakceptowana odpowiedź” jest zbyt skomplikowana. dobrze, że dodałeś swoją, zignoruj ​​zautomatyzowaną uwagę bazylii
Mickey Perlstein
Do Twojej wiadomości, strasznie kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque
Najlepsza odpowiedź, od razu do rzeczy. Zgadzam się z Mickeyem, po prostu zignoruj ​​komentarz bazylii
eramirez75
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);

To da jutrzejszą datę. c.add(...)parametry można zmienić z 1 na inną liczbę dla odpowiedniego przyrostu.

Akhilesh T.
źródło
1
możesz zrobić coś takiego jak c.setTime (obiekt Date), aby ustawić konkretną datę przed dodaniem.
Linh Lino
Chciałbym, aby domyślne pakiety java sprawiły, że obsługa dat była mniej skomplikowana ... Mam na myśli, że to taki ból za każdym razem, gdy chcesz poradzić sobie z datami ... po prostu rant ...
Shn_Android_Dev
1
@Shn_Android_Dev Klasy java.time wbudowane w Javę 8 i później wypierają straszne stare klasy dat i czas i odpowiadają na twoje życzenie. Przeniesiony również z powrotem do Java 6/7 i wcześniejszych Androida w projektach ThreeTen-Backport i ThreeTenABP . Nie musisz już nigdy używać Dateani Calendarponownie.
Basil Bourque
19

Jeśli używasz Java 8 , zrób to w ten sposób.

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

Jeśli chcesz użyć SimpleDateFormat , zrób to w ten sposób.

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
Avijit Karmakar
źródło
Nie, pytanie dotyczyło wartości tylko daty, a nie daty i godziny. Więc nie używaj tej LocalDateklasy LocalDateTime.
Basil Bourque
1
Twoja odpowiedź powtarza treść co najmniej czterech innych odpowiedzi. Wyjaśnij, w jaki sposób Twoja wartość dodana przewyższa te wartości, lub usuń je przed zebraniem głosów negatywnych.
Basil Bourque
16
long timeadj = 24*60*60*1000;
Date newDate = new Date (oldDate.getTime ()+timeadj);

Pobiera to liczbę milisekund od epoki ze starej daty i dodaje milisekundy o wartości 1 dzień, a następnie używa konstruktora publicznego Date () do utworzenia daty przy użyciu nowej wartości. Ta metoda pozwala dodać 1 dzień lub dowolną liczbę godzin / minut, nie tylko całe dni.

dvaey
źródło
Prawdopodobnie nie tego chciał OP; nie uwzględnia żadnych korekt typu czasu letniego, sekund przestępnych i tak dalej.
mrec
1
Oszczędności w ciągu dnia powinny być obsługiwane przez strefę czasową / lokalizację. Mój przykład pokazał, jak zwiększać małe czasy trwania. Przy zwiększaniu liczby dni problemem mogą być sekundy przestępne, ale przy dodawaniu godzin jest to mniej prawdopodobne, choć nadal możliwe.
dvaey,
15

Ponieważ Java 1.5 TimeUnit.DAYS.toMillis (1) wygląda dla mnie bardziej czysto.

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
źródło
Spowoduje to utworzenie wartości daty i godziny, w której Pytanie będzie zawierać tylko datę. Sugeruję, że o wiele mądrzejszym podejściem jest LocalDateklasa w klasach java.time dla Java 8 i późniejszych oraz back-port do Java 6 i Java 7 znaleziony w projekcie ThreeTen-Backport .
Basil Bourque
14

W Javie 8 prosty sposób to:

Date.from(Instant.now().plusSeconds(SECONDS_PER_DAY))
dpk
źródło
14
Wydaje się trochę rozciągnięty. Dlaczego nie po prostu pójść z Instant.now().plus( 1 , ChronoUnit.DAYS )?
Basil Bourque
Dzięki @BasilBourque
dpk
11

W java 8 możesz używać 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

Możesz przekształcić w java.util.Dateobiekt w następujący sposób.

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

Możesz sformatować LocalDatew ciąg znaków w następujący sposób.

String str = addedDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
Ramesh-X
źródło
11

To bardzo proste, próbując wyjaśnić jednym słowem. uzyskaj dzisiejszą datę, jak poniżej

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

Teraz ustaw datę z tą datą o jeden dzień za pomocą metody calendar.add, która przyjmuje (stała, wartość). Tutaj stałą może być DATA, godziny, min, s itd., A wartość jest wartością stałej. Podobnie jak w przypadku jednego dnia, stała z wyprzedzeniem to Calendar.DATE, a jej wartość to 1, ponieważ chcemy wartości z jednodniowym wyprzedzeniem.

System.out.println(calendar.getTime());// print modified date which is jutrzejsza randka

Dzięki

Kushwaha
źródło
7

Wystarczy podać datę w ciągu i liczbę kolejnych dni

 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;

}
LMK
źródło
7

Jeśli chcesz dodać jedną jednostkę czasu i spodziewasz się, że inne pola również zostaną zwiększone, możesz bezpiecznie użyć metody add. Zobacz przykład poniżej:

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

Wydrukuje:

1970-12-31
1971-01-01
1970-12-31
terrmith
źródło
Nie ma żadnej akceptowanej odpowiedzi i czułem ogólne zamieszanie, jeśli inne pola również zostaną zaktualizowane.
terrmith
7
startCalendar.add(Calendar.DATE, 1); //Add 1 Day to the current Calender
Abdurahman Popal
źródło
4
Dziękujemy za chęć wniesienia wkładu. Jest to jednak już kilka innych odpowiedzi, więc naprawdę nie widzę sensu… Poza tym IMHO nikt nie powinien używać źle zaprojektowanej i dawno przestarzałej Calendarklasy w 2019 r.
Ole VV
6

Jeśli używasz Java SE 8 lub nowszej wersji, powinieneś użyć nowego API Data / Czas

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

Jeśli musisz przekonwertować z java.util.Datena java.time.LocalDate, możesz użyć tej metody.

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

Jeśli używasz wersji wcześniejszej niż Java SE 8, radzę używać Joda-Time

Joda-Time zapewnia wysokiej jakości zamiennik klas daty i godziny Java i jest de facto standardową biblioteką daty i godziny Java przed wersją 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);
Eduardo Eljaiek
źródło
1
Twój wzór java.timeczęści jest nieprawidłowy. Powinien być dd/MM/uuuurównoważny z JodaTime.
TiiJ7
5

Użyj DateFormatinterfejsu API, aby przekonwertować ciąg na obiekt Date, a następnie użyj Calendarinterfejsu API, aby dodać jeden dzień. Daj mi znać, jeśli chcesz konkretnych przykładów kodu, a ja mogę zaktualizować swoją odpowiedź.

Ross
źródło
3

Jeśli używasz Java 8 java.time.LocalDatei java.time.format.DateTimeFormattermożesz to zrobić dość prosto.

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); 
}
Evan Hu
źródło
Jeszcze prościej: upuść formatyzator i po prostu użyj go, toString()aby wygenerować ciąg formatu rrrr-MM-dd (a jeśli nalegasz, pamiętaj, że mmto minuta, kiedy MMjest miesiąc).
Ole VV
3

Możesz użyć tego pakietu z „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);  
Shaheed
źródło
5
Sugerowanie Datezajęć w 2018 roku to kiepska rada. Kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą już starsze , wyparte przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek Oracle . Zobacz inne odpowiedzi za pomocą LocalDateklasy.
Basil Bourque
Tak, LocalDate JEST najlepszym sposobem, aby to zrobić,
Shaheed
jednak niektóre frameworki, takie jak jsf, mają małe problemy z integracją z interfejsem API czasu, więc czasami powinieneś użyć Date; plus środowisko Java <8
Lucke
1
@Lucke Większość funkcji java.time została przeniesiona z powrotem do Java 6 i 7 w projekcie ThreeTen-Backport . Dalsze dostosowanie do starszego Androida w projekcie ThreeTenABP . Więc naprawdę nie trzeba nigdy dotykać tych cholernych, okropnych, starych zajęć randkowych. Wiele ram zostało zaktualizowanych. Ale nie wszystko. Jeśli więc musisz współpracować ze starym kodem, który nie został jeszcze zaktualizowany do java.time , napisz nowy kod w java.time i przekonwertuj do / ze starych typów, wywołując nowe metody konwersji dodane do starych klas.
Basil Bourque
1
Ten kod ignoruje kluczową kwestię strefy czasowej . W danym momencie data różni się w zależności od strefy. SimpleDateFormatKlasa niestety wstrzykuje strefę czasową, w sposób dorozumiany stosowanie obowiązującego domyślną strefę JVM za. Tak więc wyniki tego kodu będą się różnić w zależności od bieżącej wartości domyślnej - i ta wartość domyślna może się zmienić w dowolnym momencie podczas działania.
Basil Bourque
3

To naprawdę proste. Jeden dzień zawiera 86400000 milisekund. Najpierw więc pobierasz bieżący czas w systemie z Systemu, System.currentTimeMillis()dodając następnie 84000000 milisekund i użyj Dateklasy, aby wygenerować format daty A dla milisekund.

Przykład

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

String Dzisiaj będzie 2019-05-9

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

Jutro smyczkowe odbędzie się 10.10.2019

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

String DayAfterTommorow będzie 11.05.2019

Mike T.
źródło
Ten kod używa okropnej Dateklasy, która została wyparta lata temu przez współczesne klasy java.time . O wiele prostsze w użyciu:LocalDate.parse( "2019-01-23" ).plusDays( 1 )
Basil Bourque
2

Wyjaśnijmy przypadek użycia: chcesz wykonywać arytmetykę kalendarza i zaczynać / kończyć z java.util.Date .

Niektóre podejścia:

  1. Konwertuj na ciąg znaków iz powrotem za pomocą SimpleDateFormat : jest to nieefektywne rozwiązanie.
  2. Konwertuj na datę lokalną : utracisz wszelkie informacje o porach dnia.
  3. Konwertuj na LocalDateTime : wymaga to więcej kroków i musisz się martwić strefą czasową.
  4. Konwertuj na epokę za pomocą Date.getTime () : Jest to wydajne, ale obliczasz za pomocą milisekund.

Rozważ użycie java.time.Instant :

Date _now = new Date();
Instant _instant = _now.toInstant().minus(5, ChronoUnit.DAYS);
Date _newDate = Date.from(_instant);
Chad Juliano
źródło
1
Nigdy nie mieszaj strasznych klas starszych, takich jak Datenowoczesne klasy java.time , takie jak Instant. W java.time zajęcia całkowicie wyprzeć klas starszych. W szczególności Instantzastępuje java.util.Date.
Basil Bourque
1
Nie odnosi się do pytania. Używasz klas reprezentujących moment (datę z porą dnia w kontekście przesunięcia lub strefy). Ale pytanie dotyczy tylko daty, bez pory dnia i strefy czasowej. Zobacz poprawną odpowiedź Sobral i poprawną odpowiedź micha.
Basil Bourque
0
Date newDate = new Date();
newDate.setDate(newDate.getDate()+1);
System.out.println(newDate);
Filip Trajcevski
źródło
14
fyi, Date.setDate () jest przestarzałe
Kelly S. French
Na moim komputerze wydaje się, że działa przez granicę miesiąca. Po Sun Apr 30 16:25:33 CEST 2017nadchodzi Mon May 01 16:25:33 CEST 2017. Jednak wciąż jest to rozwiązanie zniechęcające. Nie tylko metoda jest przestarzała z dobrego powodu, ale także w 2017 roku mamy bardzo dobre alternatywy dla Dateklasy.
Ole VV