How can I increment a day to a Java date?

Asked

Viewed 7,937 times

3

What is the best way to increase a date of the type DD/MM/YYYY?

  • Working with dates in Java has always been something terrible, one of the most adopted solutions is the JODA-TIME library, follow a tutorial: http://www.devmedia.com.br/trabando-com-joda-time/26524 But before you can test the suggestion of @ldeoliveira

4 answers

3

I suggest using the class Calendar

Date dataTeste = new Date();

Calendar cal = Calendar.getInstance(); 
cal.setTime(dataTeste ); 
cal.add(Calendar.DATE, 1);
dataTeste = cal.getTime();
  • Detail: if you want to use the current date, you do not need the setTime, for Calendar.getInstance() already obtains the current date :-)

1

The question says "increment a date of the type DD/MM/YYYY", but none of the answers focused on this specific format.

Anyway, this is a great opportunity to clarify that, as already said here, here and here:

Dates have no format

A date is just a concept, an idea: it represents a specific point in the calendar.

The date of "26 March 2019", for example, represents this: the specific point of the calendar that corresponds to the 26th of March of the year 2019. To express this idea in text form, I can write it in different ways:

  • 26/03/2019 (a common format in many countries, including Brazil)
  • 3/26/2019 (American format, reversing day and month)
  • 2019-03-26 (the format ISO 8601)
  • 26 March 2019 (in good Portuguese)
  • March 26th, 2019 (in English)
  • 2019 年 3 月 26 日 (in Japanese)
  • and many others...

Note that each of the above formats is different, but all represent the same date (the same numerical values of the day, month and year).

That said, a "date of type DD/MM/YYYY" makes no sense. A date is a specific point in the calendar, and DD/MM/YYYY is just one of many ways to represent it. You probably mean you have a String in this format? And that will only work with the day, month and year?


Assuming the above two premises (DD/MM/YYYY is the format of String and you only need to work with the day, month and year), there are some solutions, which depend on the version of Java you are using.

Java >= 8

From Java 8 you can use a java.time.format.DateTimeFormatter to create a java.time.LocalDate:

String s = "26/03/2019";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu");
LocalDate data = LocalDate.parse(s, parser);

Only that the DateTimeFormatter, by default, accepts some invalid values, such as April 31st (and automatically adjusts to April 30th). If you want to be more restricted and only accept valid dates, use a java.time.format.ResolverStyle:

DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu")
    .withResolverStyle(ResolverStyle.STRICT);

For more details about the ResolverStyle, see this answer.

The LocalDate is a class that only owns the day, month and year, so it seems to be the best choice for this case. The API has other classes, if you also need the time and time zone, for example (see this answer for more details).

To add a day to LocalDate, just use the method plusDays:

LocalDate diaSeguinte = data.plusDays(1);

Remembering that the package classes java.time are immutable, and the methods plusXXX always return another instance. In the example above, the variable data remains unchanged (it continues to correspond to 26 March 2019), and the variable diaSeguinte corresponds to March 27, 2019. Of course, if you want, you can assign the result in the same variable:

data = data.plusDays(1);

Now data is equivalent to 27 March 2019.


Java 6 and 7

For Java 6 and 7 there is the Threeten Backport, which is an excellent backport of java.time. The classes and methods are basically the same as the java.time, the difference is that they stay in the package org.threeten.bp (that is, with the exception of the package name, the code is equal to the example above).

But of course you can also use the native API (java.util.Date, java.util.Calendar and java.text.SimpleDateFormat):

// parsing da data no formato dd/MM/yyyy
String s = "26/03/2019";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(s);

// somar 1 dia
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, 1);
date = cal.getTime(); // date agora corresponde a 27/03/2019

Java 5

For Java 5, in addition to the native API, a good alternative is the Joda-Time, that has an API similar to the java.time:

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.LocalDate;

String s = "26/03/2019";
DateTimeFormatter parser = DateTimeFormat.forPattern("dd/MM/yyyy");
LocalDate date = parser.parseLocalDate(s);
date = date.plusDays(1);

Remember that Joda-Time is a closed project and on its own site there is a warning recommending the use of java.time. But for those still stuck in Java 5, it’s a better alternative than Date and Calendar.


Of course you can also work with the legacy API (Date, Calendar and SimpleDateFormat). But this hides some "traps". For example:

// supondo que o timezone default seja America/Sao_Paulo (Horário de Brasília)
TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo"));

String s = "03/11/2018"; // 3 de novembro de 2018
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(s));
System.out.println(cal.getTime()); // Sat Nov 03 00:00:00 BRT 2018

cal.add(Calendar.DATE, 1);
System.out.println(cal.getTime()); // Sun Nov 04 01:00:00 BRST 2018

I called TimeZone.setDefault only to simulate Timezone default of the JVM is America/Sao_Paulo (but let’s assume that your JVM is already set up like this). What happens in this case is that on 04/11/2018 at midnight, daylight saving time has started, and the clocks were put forward an hour. In practice, every minute between 00:00 and 00:59 is skipped, and the clock jumps directly from 23:49 to 01:00. Therefore, when adding 1 day on the date "03/11/2018 00:00", the result is "04/11/2018 01:00".

The problem of Date and Calendar is that there will always be a Timezone "acting behind the scenes" (even if in many cases you don’t realize it) and there’s not much to escape from.

Already using LocalDate, as seen above, this does not happen, since a LocalDate only has the information of the day, month and year: there is no information of the time, nor of the Timezone, and therefore this class is not affected by the settings of Timezone.


Of course, if the time and Timezone are important, you can use ZonedDateTime, which allows for greater control over the date. The detail is that, other than SimpleDateFormat, that in the example above we saw that filled the time as midnight (because the string had no time and it uses values default to fill in the missing part), in java.time we need to be explicit about what to use when a value is not present:

String s = "03/11/2018"; // 3 de novembro de 2018
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu");
ZonedDateTime date = LocalDate.parse(s, parser) // faz o parsing da string
    // adiciona horário (meia-noite)
    .atTime(LocalTime.of(0, 0))
    // escolhe um timezone
    .atZone(ZoneId.of("America/Sao_Paulo"));
date = date.plusDays(1);
System.out.println(date); // 2018-11-04T01:00-02:00[America/Sao_Paulo]

Of course still remains the "problem" of the result being day 4 to 01:00, but this is because of the daylight saving time and there is no escape from it. But the advantage is that we have more control here: I can choose the time (while SimpleDateFormat always arrow for midnight) and the Timezone (although with SimpleDateFormat also give, using the method setTimeZone).

0

With java 8 you can do it like this:

LocalDate hoje = LocalDate.now();
LocalDate amanha = hoje.plusDays(1);

0

Something like this should work(I’m not an expert on java):

String dt = "2008-01-01";  // A sua data
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.setTime(sdf.parse(dt));
c.add(Calendar.DATE, 1);  // número de dias a adicionar
dt = sdf.format(c.getTime());  // dt é a sua nova data com mais um dia

Browser other questions tagged

You are not signed in. Login or sign up in order to post.