Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
添加年份的Java日历问题_Java_Date_Calendar - Fatal编程技术网

添加年份的Java日历问题

添加年份的Java日历问题,java,date,calendar,Java,Date,Calendar,我试图增加一年的日期,但这是给不同的输入相同的日期。输入日期为2020年2月28日和2020年2月29日,输出日期与2021年2月28日相同。请帮我找出这里出了什么问题 更新: 我预计产量为2021年2月28日和2021年3月1日 public static Date dateAdd(Date newDate, int field, int amount) { Calendar aCalendar = Calendar.getInstance(); aCalend

我试图增加一年的日期,但这是给不同的输入相同的日期。输入日期为2020年2月28日和2020年2月29日,输出日期与2021年2月28日相同。请帮我找出这里出了什么问题

更新:

我预计产量为2021年2月28日和2021年3月1日

public static Date dateAdd(Date newDate, int field, int amount) {
        Calendar aCalendar = Calendar.getInstance();
        aCalendar.setTime(newDate);
        aCalendar.add(field, amount);
        return aCalendar.getTime();
    }

    public static void main(String[] args) throws Exception {

        System.out.println(dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("28/02/2020"),Calendar.YEAR,1));
        System.out.println(dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("29/02/2020"),Calendar.YEAR,1));

        // Console output below

        //Sun Feb 28 00:00:00 IST 2021
        //Sun Feb 28 00:00:00 IST 2021
    }
使用:

使用:


您可以先添加一年,然后再添加一天:

Date d = dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("28/02/2020"),Calendar.YEAR,1); // add a year
System.out.println(d);
d = dateAdd(d, Calendar.DATE, 1); // add a day
System.out.println(d);

您可以先添加一年,然后再添加一天:

Date d = dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("28/02/2020"),Calendar.YEAR,1); // add a year
System.out.println(d);
d = dateAdd(d, Calendar.DATE, 1); // add a day
System.out.println(d);

没有理由期待2021年3月1日的结果。事实上,有些人会质疑,为什么在2020年2月29日和2020年3月1日这两个日期上加上一年会产生与2021年3月1日相同的结果

相反,Java遵循一条清晰、一致且简单的规则:如果日期算术的结果(如添加月份或年份)导致无效日期,则返回的答案将是该结果月份的最后一天

例如,来自:

  • 将输入月份添加到“年度月份”字段
  • 检查结果日期是否无效
  • 如有必要,将月份日期调整为最后一个有效日期

  • 例如,2007-03-31加上一个月将导致无效日期2007-04-31。而不是返回无效结果,而是选择当月的最后一个有效日期2007-04-30。

    没有理由期望结果为2021年3月1日。事实上,有些人会质疑,为什么在2020年2月29日和2020年3月1日这两个日期上加上一年会产生与2021年3月1日相同的结果

    相反,Java遵循一条清晰、一致且简单的规则:如果日期算术的结果(如添加月份或年份)导致无效日期,则返回的答案将是该结果月份的最后一天

    例如,来自:

  • 将输入月份添加到“年度月份”字段
  • 检查结果日期是否无效
  • 如有必要,将月份日期调整为最后一个有效日期

  • 例如,2007-03-31加上一个月将导致无效日期2007-04-31。不是返回无效结果,而是选择月份的最后一个有效日期2007-04-30。

    没有问题,这取决于“添加一年”的解释,对于
    java.util.Calendar#add
    ,它是:

    添加(f,delta)
    delta
    添加到字段
    f
    。这相当于调用
    set(f,get(f)+delta)
    进行两次调整:

    添加规则1。调用后字段f的值减去调用前字段f的值为增量,以字段f中发生的任何溢出为模。当一个字段值超出其范围时会发生溢出,结果是下一个较大的字段会递增或递减,并且字段值会调整回其范围

    添加规则2。如果一个较小的字段预期是不变的,但由于字段f更改后其最小值或最大值的变化或其他约束(如时区偏移量更改)而不可能等于其先前的值,则其值将调整为尽可能接近其预期值。较小的字段表示较小的时间单位。小时是一个比月中的天小的字段。不会对预计不会保持不变的较小字段进行调整。日历系统确定哪些字段应保持不变

    此外,与set()不同,add()强制立即重新计算日历的毫秒数和所有字段

    例如:考虑GregorianCalendar最初设定为1999年8月31日。调用add(Calendar.MONTH,13)将日历设置为2000年9月30日。添加规则1将月份字段设置为9月,因为将13个月添加到8月会得到下一年的9月。由于公历月份中的日期不能是9月31日,因此添加规则2会将月份中的日期设置为30,这是最接近的可能值。虽然它是一个较小的字段,但“周中的天”不受规则2的调整,因为当月份在GregoriaCalendar中发生变化时,它会发生变化

    资料来源:


    这听起来与描述的行为一致,你期望什么&为什么?也许有更好/更专业的解决方案。

    没有错,这取决于“增加一年”的解释,对于
    java.util.Calendar#add
    ,它是:

    添加(f,delta)
    delta
    添加到字段
    f
    。这相当于调用
    set(f,get(f)+delta)
    进行两次调整:

    添加规则1。调用后字段f的值减去调用前字段f的值为增量,以字段f中发生的任何溢出为模。当一个字段值超出其范围时会发生溢出,结果是下一个较大的字段会递增或递减,并且字段值会调整回其范围

    添加规则2。如果一个较小的字段预期是不变的,但由于字段f更改后其最小值或最大值的变化或其他约束(如时区偏移量更改)而不可能等于其先前的值,则其值将调整为尽可能接近其预期值。较小的字段表示较小的时间单位。小时是一个比月中的天小的字段。不会对预计不会保持不变的较小字段进行调整。日历系统确定哪些字段应保持不变

    此外,与set()不同,add()强制立即重新计算日历的毫秒数和所有字段

    例如:考虑GregorianCalendar最初设定为1999年8月31日。调用add(Calendar.MONTH,13)将日历设置为2000年9月30日。添加规则1将月份字段设置为9月,因为将13个月添加到8月会得到下一年的9月。由于公历月份的日期不能是9月31日,因此添加规则2将月份的日期设置为30,即结束日期
    aCalendar.roll(field, amount);