Jesper
Jesper

Reputation: 999

Java Date problems, finding the date X days ago

Date nowdate = new Date();
long nowms = nowdate.getTime();
long differencems = numdaysback * 24 * 60 * 60 * 1000;
long thenms = nowms - differencems;
Date thendate = new Date(thenms);

If numdaysback is 365, then I would suppose that thendate would be one year ago. but it's not... it's about three weeks ago?!?

NUMDAYSBACK: 365
NOWDATE: Wed Jun 22 20:31:58 SGT 2011
NOWMS: 1308745918625
DIFFERENCEMS: 1471228928
THENMS: 1307274689697
THENDATE: Sun Jun 05 19:51:29 SGT 2011

Upvotes: 14

Views: 10248

Answers (5)

Kris
Kris

Reputation: 14458

If you are using Java 8 and up, you can use the newer java.time library to do this a bit more cleanly.

Date xDaysAgo = Date.from( Instant.now().minus( Duration.ofDays( x ) ) );

Upvotes: 7

nfechner
nfechner

Reputation: 17525

The Date class is (informally) deprecated. The API has so many faults, that it is really difficult to get Dates/Times right with it. The easiest example is something like your code for differencems. It fails, if the time inbetween contains a daylight savings switch (if you don't use UT) and will always fail to take care of leap seconds.

If your application depends on correct dates, you might want to use Joda Time.

Upvotes: 0

Just try this:

long differencems = numdaysback * 24L * 60 * 60 * 1000;

With the new code you will not loose the digits due to integer multiplication. Since we have marked the literal 24 as long, the multiplication will be done by auto converting the first operand numdaysback into long. The rest of the multiplication will also be done on long operands.

Upvotes: 3

Konrad Garus
Konrad Garus

Reputation: 54015

How about:

Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
Date thendate = cal.getTime();

Returns the same time of day regardless of DST or leap years, is shorter and clearer...

Generally Calendar is the way to go in such cases (unless you use a 3rd party library like Joda Time). You can use it for all kinds of calculations: add N days/hours/months/seconds, truncate time to a whole hour etc. - stuff that would be too much pain with long only.

Regarding your original question, it seems to be a victim of integer overflow. It works if the multiplication explicitly uses long:

long differencems = 365 * 24 * 60 * 60 * 1000L;

Upvotes: 29

Richard H
Richard H

Reputation: 39055

This line:

long differencems = numdaysback * 24 * 60 * 60 * 1000;

the RHS should be: 31536000000. You have something much less, the reason being the RHS is being evaluated as an int (as all the quantities are ints), and you are exceeding MAX_INT. To correct to this:

long differencems = numdaysback * 24 * 60 * 60 * 1000l;

Note the "l" which makes 1000 be a long - now the RHS will be evaluated as a long.

Upvotes: 0

Related Questions