日历字段增加会产生意外结果

德里玛

我正在创建一种方法来显示两个日期之间的时间差。为此,我正在使用日历,并减去日期以接收剩余的可用数字。但是,由于某种原因,它返回了意外的结果。这是我在扩展Date类中的方法

public String getReadableTimeDifference(Date fromDate, boolean showMilliseconds) {
    String[] result = new String[7];

    Calendar calendar = Calendar.getInstance();
    Calendar from = Calendar.getInstance();
    calendar.setTime(this);
    from.setTime(fromDate);

    // The two dates are correct. using a polymorphic method getReadableTimeDifference(boolean),
    // it supplies this method with the current date. "this" is always a date in the future.
    // Let's say that "this" is a date 10 seconds in the future:
    System.out.println(from.getTime());
    System.out.println(this);

    // Since it's 10 seconds in the future, it will print the same (2016):
    System.out.println(calendar.get(Calendar.YEAR) + " " + from.get(Calendar.YEAR));

    // It should subtract the from date (2016) from the existing date (2016)
    calendar.add(Calendar.YEAR, -from.get(Calendar.YEAR));
    calendar.add(Calendar.MONTH, -from.get(Calendar.MONTH));
    calendar.add(Calendar.DATE, -from.get(Calendar.DATE));
    calendar.add(Calendar.HOUR, -from.get(Calendar.HOUR));
    calendar.add(Calendar.MINUTE, -from.get(Calendar.MINUTE));
    calendar.add(Calendar.SECOND, -from.get(Calendar.SECOND));
    calendar.add(Calendar.MILLISECOND, -from.get(Calendar.MILLISECOND));

    // It should print "0" (because 2016-2016 = 0) but instead it prints 2.
    System.out.println(calendar.get(Calendar.YEAR));

    int years = Math.abs(calendar.get(Calendar.YEAR));
    int months = Math.abs(calendar.get(Calendar.MONTH));
    int days = Math.abs(calendar.get(Calendar.DATE));
    int hours = Math.abs(calendar.get(Calendar.HOUR));
    int minutes = Math.abs(calendar.get(Calendar.MINUTE));
    int seconds = Math.abs(calendar.get(Calendar.SECOND));
    int milliseconds = Math.abs(calendar.get(Calendar.MILLISECOND));

    if (years > 0) {
        result[0] = Utilities.prettyNumerate("year", years);
    }

    if (months > 0) {
        result[1] = Utilities.prettyNumerate("month", months);
    }

    if (days > 0) {
        result[2] = Utilities.prettyNumerate("day", days);
    }

    if (hours > 0) {
        result[3] = Utilities.prettyNumerate("hour", hours);
    }

    if (minutes > 0) {
        result[4] = Utilities.prettyNumerate("minute", minutes);
    }

    if (seconds > 0) {
        result[5] = Utilities.prettyNumerate("second", seconds);
    }

    if (milliseconds > 0 && showMilliseconds) {
        result[6] = Utilities.prettyNumerate("millisecond", milliseconds);
    }

    return Utilities.join(Utilities.clean(result), ", ", " and ");
}

prettyNumerate接受一个数字,如果所提供的字符串大于1,则在其末尾附加一个“ s”(小于-1或0)。clean清除包含任何null或空元素的数组。join通过定界符连接一个数组,最后一个元素的最终定界符。预期结果应为:

10 seconds

但是,它是:

2 years, 11 months, 31 days and 10 seconds

在此自定义日期内没有其他操作。当我实例化此自定义日期时,在完成任何自定义代码后,我都会打印出来,this.getTime()并以毫秒为单位打印正确的时间,这应该是将来的10秒。

乌尔里希

Java的Calendar对象中的year字段是相对于时代的。通过将年份设置为小于或等于0的日历,日历会通过切换时代(从AD到BC或从BC到AD)自动更正此年份。从其他领域中可以更好地了解这种行为。例如,如果将月份设置为负数,则年份会相应减少。

这些校正不是单独进行的,而是一次全部进行的,通常是在您调用getTime()读取结果日期时才进行。

因此,如果您从2016年的日期中减去2016年,则会自动更正为公元前1世纪。当您执行更多的减法时,时间实际上达到了公元前2世纪。

如一些评论中所建议,将Joda time用于用例会更好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章