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

时间:2016-06-21 13:41:20

标签: java date calendar

我正致力于创建一种方法来显示两个日期之间的时差。为此,我使用日历,并减去日期以接收剩余的可用数量。但是,出于某种原因,它会带来意想不到的结果。这是我在扩展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

clean需要一个数字并附加一个" s"如果提供的字符串超过1,则在-1或0之下。join清除任何null或空元素的数组。 10 seconds通过分隔符连接数组,并使用最后一个元素的最终分隔符。预期结果应为:

2 years, 11 months, 31 days and 10 seconds

但相反它:

this.getTime()

在此自定义日期内没有其他任何操作。当我实例化这个自定义日期时,在任何自定义代码完成后,我打印出from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter import matplotlib.pyplot as plt import numpy as np import matplotlib.tri as tri from matplotlib.ticker import MaxNLocator import os isbad =np.greater(y, 4.88) triang = tr.Triangulation(x, y) mask = np.all(np.where(isbad[triang.triangles], True, False), axis=1) triang.set_mask(mask) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') surf = ax.plot_trisurf(triang,Z,cmap=cm.jet, linewidth=0.1) fig.colorbar(surf) fig.tight_layout() ax.set_xlabel('Position of debond (% of blade length)') ax.set_ylabel('Size of debond') ax.set_zlabel(variableToDisplay) plt.show(block=False) 并打印出正确的时间(以毫秒为单位),这是将来应该的10秒。

1 个答案:

答案 0 :(得分:1)

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

这些更正不是单独进行的,而是通过调用getTime()来读出结果日期时一次性完成的。

因此,如果您从2016年的日期减去2016年,它将自动更正为公元前1世纪。当你做更多的减法时,时间实际上到了公元前2世纪。

正如一些评论中所建议的那样,最好将Joda时间用于您的用例。