如何使用Java日历从date中减去X天?

任何人都知道使用Java日历从date中减去X天的简单方法?

我一直没有find任何function,允许我直接从Java中的date中减去X天。 有人能指点我正确的方向吗?

从这里的文档中获取 :

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

 Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5). 

你可以使用add方法并传递一个负数。 但是,您也可以编写一个不使用Calendar类的简单方法,如下所示

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

这将获取date的时间戳值(自纪元起的毫秒数),并添加适当的毫秒数。 你可以传递一个负数的天数参数做减法。 这将比“正确的”日历解决scheme更简单:

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

请注意,这两个解决scheme都将Date对象作为参数进行更改,而不是返回一个全新的Date 。 如果需要,可以轻松更改其中的任何一种function。

对于简单的情况, Anson的答案可以正常工作,但是如果你打算做更复杂的date计算,我build议查看Joda时间 。 这会让你的生活更轻松。

在约达时间你可以做的

 DateTime dt = new DateTime(); DateTime fiveDaysEarlier = dt.minusDays(5); 

TL;博士

 LocalDate.now().minusDays( 10 ) 

最好指定时区。

 LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 ) 

细节

与早期版本的Java捆绑在一起的旧date时间类,如java.util.Date / .Calendar ,已经被certificate是麻烦的,混乱的和有缺陷的。 避免他们。

java.time

Java 8和后来用新的java.time框架取代了这些旧的类。 参见教程 。 由JSR 310定义,受Joda-Time的启发,并由ThreeTen-Extra项目扩展。 ThreeTen-Backport项目将类移植到Java 6和7; ThreeTenABP项目到Android。

这个问题是模糊的,不清楚它是要求只有date还是date时间。

LocalDate

对于只有date的情况,如果没有时间,则使用LocalDate类。 请注意,在决定一个date,如“今天”的关键时区。

 LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ); LocalDate tenDaysAgo = today.minusDays( 10 ); 

ZonedDateTime

如果你的意思是一个date时间,那么使用Instant类来得到UTC的时间线。 从那里,调整到一个时区获得一个ZonedDateTime对象。

 Instant now = Instant.now(); // UTC. ZoneId zoneId = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); ZonedDateTime tenDaysAgo = zdt.minusDays( 10 ); 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的遗留date时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time项目现在处于维护模式 ,build议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。

从何处获取java.time类?

  • Java SE 8SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6SE 7
    • 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
  • Android的
    • ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
    • 请参阅如何使用…。

ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如IntervalYearWeekYearQuarter 等等 。

 int x = -1; Calendar cal = ...; cal.add(Calendar.DATE, x); 

编辑:parsing器似乎不喜欢链接到Javadoc,所以这里是在明文:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int,int

addDays按照Eli的build议编写自己的addDays ,而是倾向于使用Apache的 DateUtils 。 当你需要在你的项目中使用多个地方的时候,这是非常方便的。

该API说:

addDays(Date date, int amount)

将date添加到返回新对象的date。

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

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

对乔达时代来说,这是一个有点竞争的项目,但是只有两个阶段的基础更加简单。 由于我不想使用比我的项目更大的软件包,所以它非常方便并且非常适合我需要的function。 与Java相对应的是,它的最小单位是一天,所以它实际上是一个date(而不是毫秒到几毫秒)。 一旦你创builddate,你所做的所有减去是像myDay.addDays(-5)回5天。 你可以用它来find一周中的那一天以及类似的事情。 另一个例子:

 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 } 

Eli Courtwright的第二个解决scheme是错误的,它应该是:

 Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.DATE, -days); date.setTime(c.getTime().getTime());