2

I'm making a new date object some time before current time. If I have it to show 1 day before today, it works fine. but if I want to show 30 days ago, it goes to future (?)

Date date = new Date();
long sometime = 24 * 60 * 60 * 1000; //a day
System.out.println(date.getTime() );
Date sometimeago = new Date(date.getTime() - sometime);
System.out.println(sometimeago );
sometime = 30* 24 * 60 * 60 * 1000; //a month
sometimeago = new Date(date.getTime() - sometime);
System.out.println(sometimeago );

Output:

1408160853776
Thu Aug 14 20:47:33 PDT 2014
Thu Sep 04 13:50:21 PDT 2014

What's limiting here? Reaching Long limit?

jmj
  • 237,923
  • 42
  • 401
  • 438
Kiarash
  • 7,378
  • 10
  • 44
  • 69
  • 1
    You should look at the `Calendar` class which does much of the calculation for you. – Code-Apprentice Aug 16 '14 at 03:54
  • 2
    Or better yet, the new [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) API (if you're using Java 8). Or if you can't, use JodaTime. Days aren't always 24 hours. Months aren't always 30 days. And the original date/time/calendar classes (and related formatters/parsers) had lots of issues. – Clockwork-Muse Aug 16 '14 at 03:59
  • just additional note: read about leap seconds, 24 * 60 * 60 * 1000 is not always 1 day, use calendar – Iłya Bursov Aug 16 '14 at 03:59
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 02 '17 at 05:17

2 Answers2

5

integer overflow in int literals,

in your case int literals gets evaluted before and that results in negative result and than gets assigned to long

sometime = 30* 24 * 60 * 60 * 1000; //a month 

this results in -1702967296

convert it to

sometime = 30* 24 * 60 * 60 * 1000L; //a month 

note: L to make it long literal and then multiply

Better to use Calendar class for Date manipulation


Also See

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
  • 1
    Shouldn't the `30` be `30L` to force all calculations to be longs? – Code-Apprentice Aug 16 '14 at 03:55
  • @Code if any of those is `long` the expression will get evaluated in `long` – jmj Aug 16 '14 at 04:02
  • @JigarJoshi Yes, the final value is a `long`, but there are several intermediate calculations that result in an `int` and leave open the potential for overflow. By changing the first literal to a `long`, all intermediate results will also be `long`, thus avoiding **all** potential overflow errors. – Code-Apprentice Aug 16 '14 at 04:06
0

tl;dr

LocalDate.now()
         .minusDays( 1 ) 

java.time

The modern java.time classes provide these functions.

If I have it to show 1 day before today,

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate yesterday = today.minusDays( 1 ) ;

I want to show 30 days ago

LocalDate thirtyDaysAgo = today.minusDays( 30 ) ;

Or perhaps you want a logical month rather than literally thirty days.

LocalDate monthAgo = today.minusMonths( 1 ) ;

Perhaps you want a date-time rather than a date-only value.

ZonedDateTime now = ZonedDateTime.now( z ) ;
ZonedDateTime zdtYesterday = now.minusDays( 1 ) ;
ZonedDateTime zdtThirtyDaysAgo = now.minusDays( 30 ) ;
ZonedDateTime zdtMonthAgo = now.minusMonths( 1 ) ;

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.

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