0

We have a java code snippet here

import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatExample {
public static void main(String[] args) {
    Date date = new Date();
    int days = 5;
    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    String strDate= formatter.format(date.getTime() + (days*86400000));
    System.out.println(strDate);
}
}

to add n no. of days to today's date. The result will be correct upto n=24 but gives previous month' after n=24. Why it is so?

mpsbhat
  • 2,733
  • 12
  • 49
  • 105
  • 5
    Do you have any hard requirements to use `Date`? Java8 provides [`LocalDate`](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html) which will elegantly handle date adjustments – shinjw Oct 03 '18 at 07:04
  • We are using in android app. – mpsbhat Oct 03 '18 at 07:05
  • How about `Calendar`? – Scary Wombat Oct 03 '18 at 07:05
  • `Calender` can be used. But what is the wrong in above snippet? – mpsbhat Oct 03 '18 at 07:07
  • 1
    There's also JodaTime if you're < JDK8 – shinjw Oct 03 '18 at 07:07
  • 2
    Well, `Date` is outdated – MC Emperor Oct 03 '18 at 07:20
  • 2
    In general, manipulations of dates and times are not done by adding milliseconds because there is no guarantee a day is `86400000` milliseconds (eg. when DST changes). Hence why `Calendar` is preferred. Or even better: use ThreeTenABP if you can. – TiiJ7 Oct 03 '18 at 07:22
  • 2
    @shinjw While Joda-Time is a step forward, [the ThreeTenABP library](https://github.com/JakeWharton/ThreeTenABP) will be a still bigger step. It’s the Android edition of the backport of java.time. Joda-Time has been in maintenance mode for years now. – Ole V.V. Oct 03 '18 at 08:06
  • Related: [integer giving negative values in java in multiplication using positive numbers](https://stackoverflow.com/questions/16889828/integer-giving-negative-values-in-java-in-multiplication-using-positive-numbers) – Ole V.V. Oct 03 '18 at 08:10

4 Answers4

3

The problem is the the int is overflowing

consider

    int days = 25;
    int d = days*86400000;
    System.out.println(d);

try

    int days = 25;
    long d = days*86400000L;
    System.out.println(d);
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
2

tl;dr

LocalDate               // Represent a date-only, without a time-of-day and without a time zone.
.now()                  // Capture the current date, as seen through your JVM’s current default time zone. Better to pass a `ZoneId` as the optional argument.
.plusDays( 5 )          // Add five days, returning a new `LocalDate` object. Per the Immutable Objects pattern, a new object is produced rather than changing (“mutating”) the original.
.format(                // Generate text representing the date value of our `LocalDate` object.
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) // Define a formatting pattern to suit your taste. Or call the `.ofLocalized…` methods to localize automatically. 
)                       // Returns a `String`.

java.time

Date class represents a moment in UTC, a date with a time-of-day, and an offset-from-UTC of zero. Wrong class to use when working with date-only values.

Avoid using the terrible old legacy date-time classes such as Calendar, Date, and SimpleDateFormat. These classes were supplanted years ago by the java.time classes.

Do not track days as a count of seconds or milliseconds. Days are not always 24 hours long, and years are not always 365 days long.

LocalDate

Instead, use LocalDate class.

LocalDate today = LocalDate.now() ;
LocalDate later = today.plusDays( 5 ) ;

Convert

Best to avoid the legacy classes altogether. But if you must interoperate with old code not yet updated to java.time classes, you can convert back-and-forth. Call new methods added to the old classes.

For Date you need to add a time-of-day. I expect you will want to go with the first moment of the day. And I'll assume you want to frame the date as UTC rather than a time zone. We must go through a OffsetDateTime object to add the time-of-day and offset. For the offset, we use the constant ZoneOffset.UTC. Then we extract the more basic Instant class object to convert to a java.util.Date.

OffsetDateTime odt = OffsetDateTime.of( later , LocalTime.MIN , ZoneOffset.UTC ) ;  // Combine the date with time-of-day and with an offset-from-UTC.
Instant instant = odt.toInstant() ;  // Convert to the more basic `Instant` class, a moment in UTC, always UTC by definition.
java.util.Date d = java.util.Date.from( instant ) ;  // Convert from modern class to legacy class.

Going the other direction:

Instant instant = d.toInstant() ;  // Convert from legacy class to modern class. 

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

Use days*86400000L to make this a long calculation otherwise the int value overflows.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

Try this one in your code:

Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, 5); 

strDate = formatter.format(cal.getTime());
Joe
  • 341
  • 2
  • 11
  • 1
    @ScaryWombat Yes, you are right bro, but adding days using SimpleDateFormat sounds not very wise when we have Calendar. I just thought I need to come with another solution. – Joe Oct 03 '18 at 07:22