如何使用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.Date
, Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式 ,build议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。
从何处获取java.time类?
- Java SE 8和SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和SE 7
- 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
- Android的
- ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
- 请参阅如何使用…。
ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如Interval
, YearWeek
, YearQuarter
等等 。
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,所以我一直在使用这个CalendarDate类http://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());