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

发布于 2024-07-07 15:31:14 字数 99 浏览 7 评论 0 原文

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

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

Anyone know a simple way using Java calendar to subtract X days from a date?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

请止步禁区 2024-07-14 15:31:14

摘自文档这里

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

日历日历 = Calendar.getInstance();   // 这将默认为现在 
  日历.add(日历.DAY_OF_MONTH,-5)。 
  

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).
泼猴你往哪里跑 2024-07-14 15:31:14

您可以使用 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。 如果需要,可以轻松地将任一功能更改为以其他方式执行此操作。

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

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:

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.

缱倦旧时光 2024-07-14 15:31:14

Anson 的答案 对于简单的情况来说效果很好,但是如果您要进行任何更复杂的日期计算,我建议您查看 乔达时间。 这将使您的生活变得更加轻松。

仅供参考,在乔达时间你可以做

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

Anson's answer will 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.

FYI in Joda Time you could do

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
傲性难收 2024-07-14 15:31:14

tl;dr

LocalDate.now().minusDays( 10 )

最好指定时区。

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

详细信息

与早期版本的 Java 捆绑在一起的旧日期时间类(例如 java.util.Date/.Calendar)已被证明是麻烦、混乱且有缺陷的。 避开他们。

java.time

Java 8 及更高版本用新的 java.time 框架取代了这些旧类。 请参阅教程。 由 JSR 310 定义,灵感来自 Joda-Time,并由 三十额外项目。 ThreeTen-Backport 项目将类向后移植到 Java 6 和 Java 6。 7; 将 ThreeTenABP 项目移植到 Android。

该问题含糊不清,不清楚是否要求仅日期或日期时间。

LocalDate

对于仅日期、没有时间的情况,请使用 LocalDate 类。 请注意,时区对于确定“今天”等日期至关重要。

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

ZonedDateTime

如果您指的是日期时间,请使用 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.time 框架内置于 Java 8 及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date日历,& SimpleDateFormat

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

要了解更多信息,请参阅 Oracle 教程 。 并在 Stack Overflow 上搜索许多示例和解释。 规范为 JSR 310

您可以直接与数据库交换java.time对象。 使用符合 JDBC 驱动程序 jeps/170" rel="noreferrer">JDBC 4.2 或更高版本。 不需要字符串,不需要 java.sql.* 类。

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。 该项目是 java.time 未来可能添加的内容的试验场。 您可能会在这里找到一些有用的类,例如 Interval YearWeek YearQuarter ,以及更多

tl;dr

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.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-Extra project. The ThreeTen-Backport project back-ports the classes to Java 6 & 7; the ThreeTenABP project to Android.

The Question is vague, not clear if it asks for a date-only or a date-time.

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 today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );

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 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.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project 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.

失去的东西太少 2024-07-14 15:31:14
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);

请参阅 java .util.Calendar#add(int,int)

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

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

时光磨忆 2024-07-14 15:31:14

我宁愿使用 Apache 中的 DateUtils,而不是按照 Eli 建议编写自己的 addDays。 它非常方便,尤其是当您必须在项目中的多个位置使用它时。

API 表示:

addDays(Date date, int amount)

在返回新对象的日期中添加天数。

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

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.

The API says:

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.

温柔一刀 2024-07-14 15:31:14

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

我做了如下,基本上减去24小时就是1天。
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

I faced the same challenge where I needed to go back by 1 day (should be able to roll back by one even if previous day falls into previous year or months).

I did following, basically subtracted by 24 hours for 1 day.
someDateInGregorianCalendar.add(Calendar.HOUR, -24);

Alternatively, I could also do

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

OUTPUT:

Original: Fri Jan 01 15:08:33 CET 2021
After adding DATE: Thu Dec 31 15:08:33 CET 2020
饮湿 2024-07-14 15:31:14

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

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

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());
爱殇璃 2024-07-14 15:31:14

我相信使用 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)));

如果您需要更高的精度,实例可测量到纳秒。 操作纳秒部分的方法:

minusNano()
plusNano()
getNano()

另外,请记住,日期不如即时准确。 我的建议是,如果可能的话,留在 Instant 类中。

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.Instant class.

Example for subtracting 5 days from the current time and getting the result as Date:

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

Another example for subtracting 1 hour and adding 15 minutes:

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:

minusNano()
plusNano()
getNano()

Also, keep in mind, that Date is not as accurate as Instant. My advice is to stay within the Instant class, when possible.

会发光的星星闪亮亮i 2024-07-14 15:31:14

有人推荐了 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
}

Someone recommended Joda Time so - I have been using this CalendarDate class 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:

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
}
狼亦尘 2024-07-14 15:31:14

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

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

Eli Courtwright second solution is wrong, it should be:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文