194

有人知道使用 Java 日历从日期中减去 X 天的简单方法吗?

我找不到任何函数可以让我直接从 Java 中的日期中减去 X 天。有人可以指出我正确的方向吗?

4

11 回答 11

329

取自此处的文档

根据日历的规则,在给定的日历字段中添加或减去指定的时间量。例如,要从日历的当前时间减去 5 天,可以通过调用实现:

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).
于 2008-10-17T14:17:06.800 回答
38

您可以使用该add方法并将其传递给负数。但是,您也可以编写一个不使用Calendar该类的更简单的方法,例如以下

public static void addDays(Date d, int days)
{
    d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}

这将获取日期的时间戳值(自纪元以来的毫秒数)并添加适当的毫秒数。您可以为 days 参数传递一个负整数来进行减法。这将比“正确”的日历解决方案更简单:

public static void addDays(Date d, int days)
{
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    c.add(Calendar.DATE, days);
    d.setTime( c.getTime().getTime() );
}

请注意,这两种解决方案都会更改Date作为参数传递的对象,而不是返回一个全新的Date. 如果需要,可以轻松更改任一功能以另一种方式进行。

于 2008-10-17T14:22:03.373 回答
36

Anson 的答案适用于简单的情况,但如果您要进行更复杂的日期计算,我建议您查看Joda Time。它会让你的生活更轻松。

仅供参考,你可以在 Joda Time

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
于 2008-10-17T14:24:34.273 回答
22
于 2015-11-04T19:56:49.330 回答
8
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);

java.util.Calendar#add(int,int)

于 2008-10-17T14:17:49.183 回答
5

与其addDays按照 Eli 的建议编写我自己的,我更愿意使用DateUtilsfrom Apache。它很方便,尤其是当您必须在项目中的多个位置使用它时。

API 说:

addDays(Date date, int amount)

将天数添加到返回新对象的日期。

请注意,它返回一个新Date对象,并且不会对前一个对象本身进行更改。

于 2012-08-13T12:29:32.743 回答
2

可以通过以下方式轻松完成

Calendar calendar = Calendar.getInstance();
        // from current time
        long curTimeInMills = new Date().getTime();
        long timeInMills = curTimeInMills - 5 * (24*60*60*1000);    // `enter code here`subtract like 5 days
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());

        // from specific time like (08 05 2015)
        calendar.set(Calendar.DAY_OF_MONTH, 8);
        calendar.set(Calendar.MONTH, (5-1));
        calendar.set(Calendar.YEAR, 2015);
        timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000);
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());
于 2017-12-19T06:37:01.197 回答
2

我相信使用java.time.Instant类可以实现一种干净而漂亮的方法来执行任何时间单位(月、天、小时、分钟、秒……)的减法或加法。

从当前时间减去 5 天并将结果作为日期的示例:

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

另一个减 1 小时加 15 分钟的例子:

Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));

如果您需要更高的精度,Instance 可以测量到纳秒级。处理纳秒部分的方法:

minusNano()
plusNano()
getNano()

另外,请记住,Date 不如 Instant 准确。我的建议是尽可能留在 Instant 类中。

于 2019-12-09T13:11:55.163 回答
1

有人推荐了 Joda Time - 我一直在使用这个CalendarDatehttp://calendardate.sourceforge.net

这对 Joda Time 来说是一个有点竞争的项目,但在只有 2 节课时更加基础。因为我不想使用比我的项目更大的包,所以它非常方便并且非常适合我需要的东西。与 Java 对应物不同,它的最小单位是天,所以它实际上是一个日期(没有精确到毫秒或其他什么)。创建日期后,您要做的只是减去 myDay.addDays(-5) 之类的内容,以返回 5 天。您可以使用它来查找星期几之类的东西。另一个例子:

CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);

和:

//print 4 previous days of the week and today
String dayLabel = "";
CalendarDate today = new CalendarDate(TimeZone.getDefault());
CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon"
CalendarDate currDay = today.addDays(-4);
while(!currDay.isAfter(today)) {
    dayLabel = cdf.format(currDay);
    if (currDay.equals(today))
        dayLabel = "Today";//print "Today" instead of the weekday name
    System.out.println(dayLabel);
    currDay = currDay.addDays(1);//go to next day
}
于 2011-10-27T20:33:46.667 回答
0

Eli Courtwright 的第二个解决方案是错误的,应该是:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
于 2009-09-25T09:30:16.083 回答
0

我面临着同样的挑战,我需要回退 1 天(即使前一天落入前一年或前几个月,也应该能够回滚一天)。

我做了以下,基本上减去了 1 天的 24 小时。someDateInGregorianCalendar.add(Calendar.HOUR, -24);

或者,我也可以这样做

GregorianCalendar cal = new GregorianCalendar();
    cal.set(Calendar.YEAR, 2021);
    cal.set(Calendar.MONTH, 0);
    cal.set(Calendar.DATE, 1);
    System.out.println("Original: " + cal.getTime());
    cal.add(Calendar.DATE, -1);
    System.out.println("After adding DATE: " + cal.getTime());

输出:

Original: Fri Jan 01 15:08:33 CET 2021
After adding DATE: Thu Dec 31 15:08:33 CET 2020
于 2021-10-25T12:59:05.627 回答