32

我在 Jasper Reports 中创建了一份报告,它只识别 java.util.Date(不是日历或公历等)。

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

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

new Date(New Date() - 7)

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

4

11 回答 11

59

从现在开始:

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 小时之前的日期/时间。

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

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

否则,您可能需要补偿您的7 days earlier实际并不完全是 168 小时(由于 DST 在该时间范围内开始或结束)。

于 2011-02-04T20:41:42.113 回答
32

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

import java.util.GregorianCalendar;
import java.util.Date;

Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysAgo = cal.getTime();
于 2011-02-04T20:38:18.683 回答
13

尝试

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

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

于 2011-02-04T20:38:25.440 回答
12

由于尚未有人提及TimeUnit

new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
于 2016-04-06T12:11:53.293 回答
6

基于 Java 8 的解决方案:

new Date(
     Instant.now().minus(7, ChronoUnit.DAYS)
     .toEpochMilli()
)
于 2019-08-13T19:05:10.753 回答
5

试试这个:

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
return c.getTime();
于 2011-02-04T20:40:30.140 回答
4

确定的“天”需要时区。时区定义了“一天”的开始时间。时区包括处理夏令时和其他异常情况的规则。使时区无关紧要并没有什么魔法。如果您忽略此问题,将应用 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没有 time zone, DateTime 有。因此,分配所需/适当的时区来决定什么是“天”以及它们何时开始。

反之,将 DateTime 转换为 juDate,只需调用该toDate方法即可。

java.util.Date date = dateTime.toDate();
于 2014-06-21T01:56:31.527 回答
3

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

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

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

于 2014-06-19T14:36:15.627 回答
1

你可以试试这个

    Calendar c = Calendar.getInstance();
    c.add(Calendar.DAY_OF_MONTH, -7);
    System.out.println(new java.sql.Date(c.getTimeInMillis()));
于 2019-01-11T11:36:08.013 回答
0

由于热烈的讨论:

该问题可能没有指定时区的正确答案。

下面是一些使用默认(因此不推荐)时区工作的代码,该时区考虑了默认时区夏令时。

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

请不要为答案投票。

于 2011-02-04T22:13:43.743 回答
0

我这样做:

Date oneWeekAgo = DateUtils.addDays(DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH), -7);
于 2017-10-06T14:28:00.203 回答