java.util.Date:七天前

我在Jasper Reports中创建了一个报告,它只识别java.util.Date(不是Calendar或Gregorian等)。

有没有办法在当前日期前7天创建日期?

理想情况下,它看起来像这样:

new Date(New Date() - 7) 

更新:我不能强调这一点:JasperReports不会识别Java Calendar对象。

从现在开始:

 long DAY_IN_MS = 1000 * 60 * 60 * 24; new Date(System.currentTimeMillis() - (7 * DAY_IN_MS)) 

从任意Date date

 new Date(date.getTime() - (7 * DAY_IN_MS)) 

编辑:正如其他答案所指出的,如果这是一个因素,则不考虑夏令时。

只是为了澄清我所说的限制:

对于受夏令时影响的人 ,如果7 days earlier ,你的意思是,如果现在是12pm noon on 14 Mar 2010 ,你想要7 days earlier计算到12pm on 7 Mar 2010 ,那么要小心。

此解决方案准确地找到24小时* 7天= 168小时之前的日期/时间。

然而,当这个解决方案发现,例如(14 Mar 2010 1:00pm) - 7 * DAY_IN_MS时,有些人会感到惊讶 (14 Mar 2010 1:00pm) - 7 * DAY_IN_MS 可能会返回结果(7 Mar 2010 12:00pm) ,其中您的时区的挂钟时间不是两个日期/时间( 1pm 12pm )之间相同。 这是因为当晚开始或结束的夏令时以及“挂钟时间”失去或获得一小时。

如果DST不是您的一个因素,或者您确实需要(168 hours) (无论挂钟时间的变化),那么此解决方案可以正常工作。

否则,您可能需要补偿您7 days earlier确切时间并非真正意味着168小时(由于DST在该时间范围内开始或结束)。

使用Calendar的工具使用getTime()创建新的Date对象:

 import java.util.GregorianCalendar; import java.util.Date; Calendar cal = new GregorianCalendar(); cal.add(Calendar.DAY_OF_MONTH, -7); Date sevenDaysAgo = cal.getTime(); 

尝试

  Date sevenDay = new Date(System.currentTimeMillis() - 7L * 24 * 3600 * 1000)); 

另一种方法是使用日历,但我不喜欢自己使用它。

尝试这个:

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

既然没有人提到过TimeUnit

 new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) 

我不确定他们何时添加了这些,但JasperReports有自己的一套“函数”可以操作日期。 这是一个我没有彻底测试过的例子:

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

这将构建一个java.util.Date ,其日期设置为从今天起7天。 如果您想使用不同的“锚点”日期,只需将TODAY()替换为您要使用的日期。

确定“天”需要时区。 时区定义“日”开始的时间。 时区包括处理夏令时和其他exception的规则。 没有什么魔力使时区变得无关紧要。 如果忽略该问题,将应用JVM的默认时区。 这往往会导致混乱和痛苦。

避免使用java.util.Date

众所周知,java.util.Date和.Calendar类很麻烦。 避免他们。 它们非常糟糕,Sun / Oracle同意用Java 8中的新java.time包取代它们。使用它或者Joda-Time 。

乔达时间

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

一天的第一个瞬间

或者,您可能希望将时间调整为当天的第一时刻,以便捕获一整天的时间。 使用withTimeAtStartOfDay调用方法。 请记住,这通常是00:00:00但并非总是如此。

避免使用Joda-Time中的“午夜”方法和类。 它们基于一个错误的概念,现在已被弃用。

 DateTime dateTimeStart = new DateTime( new java.util.Date(), timeZone ).withTimeAtStartOfDay(); // Not necessarily the time "00:00:00". DateTime weekAgo = dateTime.minusDays( 7 ).withTimeAtStartOfDay(); 

转换为/从juDate转换

如上所示,要从java.util.Date转换为Joda-Time,只需将Date对象传递给DateTime的构造函数。 了解juDate 没有时区 ,DateTime可以。 因此,请指定所需/适当的时区,以确定“天”是什么以及何时开始。

换句话说,DateTime到juDate,只需调用toDate方法。

 java.util.Date date = dateTime.toDate(); 

由于热烈的讨论:

问题可能没有适当的答案,没有指定的时区。

下面是一些代码工作w /默认(因此已弃用)时区考虑到默认时区夏令时。

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

虽然解决方案确实有效,但它与假设时区一样虚假。

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

请不要投票给答案。

有没有理由不能在你的支持bean中进行计算? 然后将其作为参数发送到您的报告中。

我是这样做的:

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