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

IT小君   2021-09-15T07:54:01

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

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

点击广告,支持我们为你提供更好的服务
评论(10)
IT小君

取自此处的文档

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

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).
2021-09-15T07:54:01   回复
IT小君

您可以使用该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. 如果需要,任何一个功能都可以轻松更改为另一种方式。

2021-09-15T07:54:01   回复
IT小君

Anson 的答案适用于简单的情况,但如果您要进行更复杂的日期计算,我建议您查看Joda Time它会让你的生活更轻松。

仅供参考 Joda Time 你可以做

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
2021-09-15T07:54:01   回复
IT小君

tl;博士

LocalDate.now().minusDays( 10 )

最好指定时区。

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

细节

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

时间

Java 8 及更高版本用新的 java.time 框架取代了那些旧类。请参阅教程JSR 310定义,受Joda-Time启发,并由ThreeTen-Extra项目扩展ThreeTen-Backport 项目将类向后移植到 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 中的日期时间类型表,包括现代的和传统的。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

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

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

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

从哪里获得 java.time 类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多

2021-09-15T07:54:02   回复
IT小君
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);

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

2021-09-15T07:54:02   回复
IT小君

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

API 说:

addDays(Date date, int amount)

将天数添加到返回新对象的日期。

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

2021-09-15T07:54:02   回复
IT小君

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

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());
2021-09-15T07:54:02   回复
IT小君

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

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

minusNano()
plusNano()
getNano()

另外,请记住,Date 不如 Instant 准确。我的建议是尽可能留在 Instant 类中

2021-09-15T07:54:03   回复
IT小君

有人推荐 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
}
2021-09-15T07:54:03   回复
IT小君

Eli Courtwright 第二种解法是错误的,应该是:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
2021-09-15T07:54:03   回复