开发者

java.util.Date: seven days ago

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 the current date?

Ideally, it would look something like this:

new Date(N开发者_StackOverflowew Date() - 7)

UPDATE: I can't emphasize this enough: JasperReports DOES NOT RECOGNIZE Java Calendar objects.


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();


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))


Java 8 based solution:

new Date(
     Instant.now().minus(7, ChronoUnit.DAYS)
     .toEpochMilli()
)


Try this:

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
return c.getTime();


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.

Avoid java.util.Date

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.

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 );

First Moment Of Day

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(); 

Convert To/From j.u.Date

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();


I'm not sure when they added these, but JasperReports has their own set of "functions" that can manipulate dates. Here is an example that I haven't tested thoroughly:

DATE(YEAR(TODAY()), MONTH(TODAY()), DAY(TODAY()) - 7)

That builds a java.util.Date with the date set to 7 days from today. If you want to use a different "anchor" date, just replace TODAY() with whatever date you want to use.


You can try this,

    Calendar c = Calendar.getInstance();
    c.add(Calendar.DAY_OF_MONTH, -7);
    System.out.println(new java.sql.Date(c.getTimeInMillis()));


Due to the heated discussion:

The question may not have a proper answer w/o a designated timezone.

below it is some code to work w/ the default (and hence deprecated) timezone that takes into account the default timezone daylight saving.

Date date= new Date();
date.setDate(date.getDate()-7);//date works as calendar w/ negatives

While the solution does work, it is exactly as bogus as in terms of assuming the timezone.

new Date(System.currentTimeMillis() - 10080*60000);//a week has 10080 minutes

Please, don't vote for the answer.


I'm doing it this way :

Date oneWeekAgo = DateUtils.addDays(DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH), -7);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜