如何使用Java日历从日期中减去X天?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/212321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to subtract X days from a date using Java calendar?
提问by fmsf
Anyone know a simple way using Java calendar to subtract X days from a date?
有人知道使用 Java 日历从日期中减去 X 天的简单方法吗?
I have not been able to find any function which allows me to directly subtract X days from a date in Java. Can someone point me to the right direction?
我找不到任何允许我直接从 Java 中的日期减去 X 天的函数。有人可以指出我正确的方向吗?
采纳答案by Anson Smith
Taken from the docs here:
取自此处的文档:
Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules. For example, to subtract 5 days from the current time of the calendar, you can achieve it by calling:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
根据日历的规则,在给定的日历字段中添加或减去指定的时间量。例如,要从日历的当前时间减去 5 天,可以通过调用来实现:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
回答by matt b
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
edit: the parser doesn't seem to like the link to the Javadoc, so here it is in plaintext:
编辑:解析器似乎不喜欢 Javadoc 的链接,所以这里是纯文本:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int, int)
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int, int)
回答by Eli Courtwright
You could use the add
method and pass it a negative number. However, you could also write a simpler method that doesn't use the Calendar
class such as the following
您可以使用该add
方法并将其传递给负数。但是,您也可以编写一个不使用Calendar
类的更简单的方法,如下所示
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
This gets the timestamp value of the date (milliseconds since the epoch) and adds the proper number of milliseconds. You could pass a negative integer for the days parameter to do subtraction. This would be simpler than the "proper" calendar solution:
这将获取日期的时间戳值(自纪元以来的毫秒数)并添加适当的毫秒数。您可以为 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() );
}
Note that both of these solutions change the Date
object passed as a parameter rather than returning a completely new Date
. Either function could be easily changed to do it the other way if desired.
请注意,这两种解决方案都会更改Date
作为参数传递的对象,而不是返回一个全新的Date
. 如果需要,任何一个功能都可以轻松更改为另一种方式。
回答by Mike Deck
Anson's answerwill work fine for the simple case, but if you're going to do any more complex date calculations I'd recommend checking out Joda Time. It will make your life much easier.
Anson 的答案适用于简单的情况,但如果您要进行更复杂的日期计算,我建议您查看Joda Time。它会让你的生活更轻松。
FYI in Joda Time you could do
仅供参考 Joda Time 你可以做
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
回答by user178973
Eli Courtwright second solution is wrong, it should be:
Eli Courtwright 第二种解法是错误的,应该是:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
回答by mikato
Someone recommended Joda Time so - I have been using this CalendarDateclass http://calendardate.sourceforge.net
有人推荐 Joda Time 所以 - 我一直在使用这个CalendarDate类 http://calendardate.sourceforge.net
It's a somewhat competing project to Joda Time, but much more basic at only 2 classes. It's very handy and worked great for what I needed since I didn't want to use a package bigger than my project. Unlike the Java counterparts, its smallest unit is the day so it is really a date (not having it down to milliseconds or something). Once you create the date, all you do to subtract is something like myDay.addDays(-5) to go back 5 days. You can use it to find the day of the week and things like that. Another example:
这是一个与 Joda Time 有点竞争的项目,但在只有 2 个班级时更加基础。它非常方便并且非常适合我需要的东西,因为我不想使用比我的项目更大的包。与 Java 对应的版本不同,它的最小单位是天,因此它实际上是一个日期(不是将它缩小到毫秒或其他什么东西)。创建日期后,您要做的就是减去 myDay.addDays(-5) 之类的东西,以返回 5 天。您可以使用它来查找星期几之类的内容。另一个例子:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
And:
和:
//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
}
回答by Risav Karna
Instead of writing my own addDays
as suggested by Eli, I would prefer to use DateUtils
from Apache. It is handy especially when you have to use it multiple places in your project.
addDays
我宁愿使用DateUtils
from Apache,而不是按照 Eli 的建议自己编写。它非常方便,尤其是当您必须在项目中的多个地方使用它时。
The API says:
API 说:
addDays(Date date, int amount)
addDays(Date date, int amount)
Adds a number of days to a date returning a new object.
将天数添加到返回新对象的日期。
Note that it returns a new Date
object and does not make changes to the previous one itself.
请注意,它返回一个新Date
对象并且不会对前一个对象本身进行更改。
回答by Basil Bourque
tl;dr
tl;博士
LocalDate.now().minusDays( 10 )
Better to specify time zone.
最好指定时区。
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Details
细节
The old date-time classes bundled with early versions of Java, such as java.util.Date
/.Calendar
, have proven to be troublesome, confusing, and flawed. Avoid them.
与早期 Java 版本捆绑在一起的旧日期时间类(例如java.util.Date
/ .Calendar
)已被证明是麻烦、混乱和有缺陷的。避开它们。
java.time
时间
Java 8 and later supplants those old classes with the new java.time framework. See Tutorial. Defined by JSR 310, inspired by Joda-Time, and extended by theThreeTen-Extraproject. The ThreeTen-Backport project back-ports the classes to Java 6 & 7; the ThreeTenABP project to Android.
Java 8 及更高版本用新的 java.time 框架取代了那些旧类。请参阅教程。由JSR 310定义,受Joda-Time启发,并由ThreeTen-Extra项目扩展。ThreeTen-Backport 项目将类向后移植到 Java 6 和 7;ThreeTenABP 项目到 Android。
The Question is vague, not clear if it asks for a date-only or a date-time.
问题含糊不清,不清楚它是要求仅日期还是日期时间。
LocalDate
LocalDate
For a date-only, without time-of-day, use the LocalDate
class. Note that a time zone in crucial in determining a date such as "today".
对于仅日期,没有时间,使用LocalDate
类。请注意,时区对于确定“今天”等日期至关重要。
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
ZonedDateTime
If you meant a date-time, then use the Instant
class to get a moment on the timeline in UTC. From there, adjust to a time zone to get a ZonedDateTime
object.
如果您的意思是日期时间,则使用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 );
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- java.time 类的更高版本的 Android 捆绑实现。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by rab
It can be done easily by the following
可以通过以下方式轻松完成
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());
回答by Yordan Boev
I believe a clean and nice way to perform subtraction or addition of any time unit (months, days, hours, minutes, seconds, ...) can be achieved using the java.time.Instantclass.
我相信使用java.time.Instant类可以实现对任何时间单位(月、日、小时、分钟、秒……)进行减法或加法的干净而漂亮的方法。
Example for subtracting 5 days from the current time and getting the result as Date:
从当前时间减去 5 天并将结果作为日期的示例:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Another example for subtracting 1 hour and adding 15 minutes:
减去 1 小时加 15 分钟的另一个示例:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
If you need more accuracy, Instance measures up to nanoseconds. Methods manipulating nanosecond part:
如果您需要更高的精度,Instance 可以测量到纳秒。操作纳秒部分的方法:
minusNano()
plusNano()
getNano()
Also, keep in mind, that Date is not as accurate as Instant.
另外,请记住,Date 不如 Instant 准确。