I have a report created in Jasper Reports which ONLY recognizes java.util.Date\'s (not Calendar or Gregorian, etc).
Is there a way to create a date 7 days prior to t
From exactly now:
long DAY_IN_MS = 1000 * 60 * 60 * 24;
new Date(System.currentTimeMillis() - (7 * DAY_IN_MS))
From arbitrary Date date
:
new Date(date.getTime() - (7 * DAY_IN_MS))
Edit: As pointed out in the other answers, does not account for daylight savings time, if that's a factor.
Just to clarify that limitation I was talking about:
For people affected by daylight savings time, if by 7 days earlier
, you mean that if right now is 12pm noon on 14 Mar 2010
, you want the calculation of 7 days earlier
to result in 12pm on 7 Mar 2010
, then be careful.
This solution finds the date/time exactly 24 hours * 7 days= 168 hours earlier.
However, some people are surprised when this solution finds that, for example, (14 Mar 2010 1:00pm) - 7 * DAY_IN_MS
may return a result in(7 Mar 2010 12:00pm)
where the wall-clock time in your timezone isn't the same between the 2 date/times (1pm
vs 12pm
). This is due to daylight savings time starting or ending that night and the "wall-clock time" losing or gaining an hour.
If DST isn't a factor for you or if you really do want (168 hours)
exactly (regardless of the shift in wall-clock time), then this solution works fine.
Otherwise, you may need to compensate for when your 7 days earlier
doesn't really mean exactly 168 hours (due to DST starting or ending within that timeframe).
Use Calendar's facility to create new Date objects using getTime()
:
import java.util.GregorianCalendar;
import java.util.Date;
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysAgo = cal.getTime();
Java 8 based solution:
new Date(
Instant.now().minus(7, ChronoUnit.DAYS)
.toEpochMilli()
)
try
Date sevenDay = new Date(System.currentTimeMillis() - 7L * 24 * 3600 * 1000));
Another way is to use Calendar but I don't like using it myself.
Since no one has mentioned TimeUnit
yet:
new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
A determining "days" requires a time zone. A time zone defines when a "day" begins. A time zone includes rules for handling Daylight Saving Time and other anomalies. There is no magic to make time zones irrelevant. If you ignore the issue, the JVM's default time zone will be applied. This tends to lead to confusion and pain.
The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. They are so bad that Sun/Oracle agreed to supplant them with the new java.time package in Java 8. Use either that or Joda-Time.
Example code in Joda-Time 2.3.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Specify or else the JVM's default will apply.
DateTime dateTime = new DateTime( new java.util.Date(), timeZone ); // Simulate passing a Date.
DateTime weekAgo = dateTime.minusDays( 7 );
Or, you may want to adjust the time-of-day to the first moment of the day so as to capture an entire day's worth of time. Call the method withTimeAtStartOfDay
. Keep in mind this is usually 00:00:00
but not always.
Avoid the "midnight" methods and classes in Joda-Time. They are based on a faulty concept and are now deprecated.
DateTime dateTimeStart = new DateTime( new java.util.Date(), timeZone ).withTimeAtStartOfDay(); // Not necessarily the time "00:00:00".
DateTime weekAgo = dateTime.minusDays( 7 ).withTimeAtStartOfDay();
As seen above, to convert from java.util.Date to Joda-Time merely pass the Date object to constructor of DateTime. Understand that a j.u.Date has no time zone, a DateTime does. So assign the desired/appropriate time zone for deciding what "days" are and when they start.
To go the other way, DateTime to j.u.Date, simply call the toDate
method.
java.util.Date date = dateTime.toDate();