如何使用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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:26:10  来源:igfitidea点击:

How to subtract X days from a date using Java calendar?

javacalendarsubtraction

提问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 addmethod and pass it a negative number. However, you could also write a simpler method that doesn't use the Calendarclass 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 Dateobject 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 所以 - 我一直在使用这个CalendarDatehttp://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 addDaysas suggested by Eli, I would prefer to use DateUtilsfrom Apache. It is handy especially when you have to use it multiple places in your project.

addDays我宁愿使用DateUtilsfrom 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 Dateobject 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 LocalDateclass. 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 Instantclass to get a moment on the timeline in UTC. From there, adjust to a time zone to get a ZonedDateTimeobject.

如果您的意思是日期时间,则使用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 );

Table of date-time types in Java, both modern and legacy.

Java 中的日期时间类型表,包括现代的和传统的。



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 类?

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 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多

回答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 准确。