31

为什么当我在今天加上 30 天时,我得到了今天 - 30,当我加上 20 时,它增加了?

这是一个样本

import java.text.DateFormat;
import java.util.Date;

public class DatePlus
{

    public static void main(String[] args)
    {
        Date now = new Date();
        Date now1 = new Date();
        Date now2 = new Date();
        DateFormat currentDate = DateFormat.getDateInstance();

        Date addedDate1 = addDays(now2, 20);
        Date addedDate2 = addDays(now1, 30);
        System.out.println(currentDate.format(now));
        System.out.println(currentDate.format(addedDate1));
        System.out.println(currentDate.format(addedDate2));
    }

    public static Date addDays(Date d, int days)
    {
        d.setTime(d.getTime() + days * 1000 * 60 * 60 * 24);
        return d;
    }
}

“这是控制台”

Jul 30, 2012
Aug 19, 2012
Jul 10, 2012
4

7 回答 7

61

使用日历。 http://docs.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html

伪代码:

Calendar c= Calendar.getInstance();
c.add(Calendar.DATE, 30);
Date d=c.getTime();
于 2012-07-30T19:08:07.687 回答
35

这是因为30 * 1000 * 60 * 60 * 24溢出Integer.MAX_VALUE,而20 * 1000 * 60 * 60 * 24没有。

于 2012-07-30T19:12:40.173 回答
20
  1. Date不受人类使用的任何日历系统的约束。它只代表时间点。加30 天Date毫无意义,就像给红色加 20 天一样。

  2. 添加的常用方法1000 * 60 * 60 * 24是错误的。您正在添加 86400 秒,但一天不一定长 86400 秒。,它可能会更长或更短一小时。由于闰秒,它可能会更长或更短一秒。

  3. 应该做的是转换DateCalendar( 它实际上代表一些日历系统,例如GregorianCalendar. 然后只需添加天数:

    Calendar calendar = new GregorianCalendar(/* remember about timezone! */);
    calendar.setTime(date);
    calendar.add(Calendar.DATE, 30);
    date = calendar.getTime();
    
  4. DateUtils.addDays()从 Apache Commons Lang使用:

    DateUtils.add(date, 30);
    

    这不违反上面写的内容,它转换为Calendar下面的内容。

  5. 或者完全避免这个地狱,去乔达时间

于 2012-07-30T19:09:28.593 回答
5

days是一个整数。

30 * 1000 * 60 * 60 * 24 是 2,592,000,000,大于 2,147,483,647(Java 中最大的 int)。你有一个缓冲区溢出,你的结果是一个相当小的负数(以二进制检查,转换回 int 作为 2 补码)

简单的解决方法是将其中一个值转换为 long,以便表达式的结果存储为 long,它可以保存该值而不会溢出。

 (long) days * 1000L * 60 * 60 * 24

总是建议使用 Calendar 或其他 api(我听说过 JodaTime,但没有使用它)来操作日期。

于 2012-07-30T19:15:13.743 回答
5
于 2016-06-04T08:45:24.900 回答
4

您在计算中遇到整数溢出。天数 * 1000 * 60 * 60 * 24 的值大于天数 = 30 时允许有符号整数的最大值,但天数 = 20 时则不允许。当您递增一个有符号整数时,它的最大可能值,而不是增加值,符号翻转并变为负数!这就是您的日期倒退的原因 - 您正在向其添加一个负数。

要解决此问题,您可以使用 long 数据类型,它的最大值比整数大得多,如下所示:

long secondsToAdd = days;
secondsToAdd *= (1000*60*60*24);
d.setTime(d.getTime() + secondsToAdd);
于 2012-07-30T19:18:57.197 回答
0

使用此功能:

public static String addToCurrentDate(String format,int day,int month,int year){

        DateFormat dateFormat = new SimpleDateFormat(format);

        Calendar calendarInstance = Calendar.getInstance();
        calendarInstance.add(Calendar.YEAR, year);
        calendarInstance.add(Calendar.MONTH, month);
        calendarInstance.add(Calendar.DATE, day);
        return dateFormat.format(calendarInstance.getTime());
    }
于 2019-03-10T15:28:45.977 回答