如何获得从现在到未来时间的月,周,日和小时数?

我需要找出使用Java从现在到未来时间剩下的月,周,日和小时数。 我不能使用像Joda这样的任何第三方库。 我怎么能只使用JDK类呢?

到目前为止,这是我想出的。 除了某些情况外,它有点工作:

public class DateUtil { public static Integer[] components(Date from, Date to) { Integer[] result = new Integer[4]; //SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //df.setTimeZone(TimeZone.getTimeZone("EST")); Calendar fromCal = new GregorianCalendar(); Calendar toCal = new GregorianCalendar(); fromCal.setTime(from); toCal.setTime(to); int months = 0; do { fromCal.add(Calendar.MONTH, 1); ++months; //System.out.println(df.format(fromCal.getTime())); } while (fromCal.before(toCal)); fromCal.add(Calendar.MONTH, -1); --months; int days = 0; do { fromCal.add(Calendar.DAY_OF_YEAR, 1); ++days; } while (fromCal.before(toCal)); fromCal.add(Calendar.DAY_OF_YEAR, -1); --days; int hours = 0; do { fromCal.add(Calendar.HOUR_OF_DAY, 1); ++hours; } while (fromCal.before(toCal)); fromCal.add(Calendar.HOUR_OF_DAY, -1); --hours; int minutes = 0; do { fromCal.add(Calendar.MINUTE, 1); ++minutes; } while (fromCal.before(toCal)); result[0] = months; result[1] = days; result[2] = hours; result[3] = minutes; return result; } public static void main(String[] args) { try { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); df.setTimeZone(TimeZone.getTimeZone("EST")); Date from = df.parse("2014-03-29 00:00"); Date to = df.parse("2014-05-29 00:00"); Integer result[] = components(from, to); System.out.printf("Months:%02d Days:%02d Hrs:%02d Mins:%02d\n", result[0], result[1], result[2], result[3]); } catch (Exception e) { e.printStackTrace(); } } } 

如果您有2月中间且开始日期是月末,则会产生不可接受的结果。 例如:

来自:2013年12月31日至:2014年12月31日

差异将产生:12个月,3天。

为什么不使用Java类Date和Calendar

这些类已具有内置function,可帮助您计算两个日期之间的差异。 大多数Date方法似乎都被弃用了,所以我建议使用Calendar。 祝好运!

我的一位同事最终得出了正确的答案。 逐步向日历添加月份的问题是您从1月31日到2月28日到3月28日,而不是3月31日。这会增加不准确性。 解决方案是在原始开始日期添加1个月,2个月,3个月等。 然后你从1月31日到2月28日到3月31日。无论如何,这是他的解决方案,我稍微改变了。

 public class TimeSpan { public int months; public int days; public int hours; public int minutes; } class DateCalculator { public static TimeSpan difference(Date later, Date earlier) { TimeSpan v = new TimeSpan(); /* Add months until we go past the target, then go back one. */ while (calculateOffset(earlier, v).compareTo(later) <= 0) { v.months++; } v.months--; /* Add days until we go past the target, then go back one. */ while (calculateOffset(earlier, v).compareTo(later) <= 0) { v.days++; } v.days--; /* Add hours until we go past the target, then go back one. */ while (calculateOffset(earlier, v).compareTo(later) <= 0) { v.hours++; } v.hours--; while (calculateOffset(earlier, v).compareTo(later) <= 0) { v.minutes++; } v.minutes--; return v; } private static Date calculateOffset(Date start, TimeSpan offset) { Calendar c = new GregorianCalendar(); c.setTime(start); c.add(Calendar.MONTH, offset.months); c.add(Calendar.DAY_OF_YEAR, offset.days); c.add(Calendar.HOUR, offset.hours); c.add(Calendar.MINUTE, offset.minutes); return c.getTime(); } public static void main(String[] args) { try { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); df.setTimeZone(TimeZone.getTimeZone("EST")); Date from = df.parse("2013-01-31 00:00"); Date to = df.parse("2014-01-31 10:20"); TimeSpan ts = difference(to, from); System.out.printf("Months:%02d Days:%02d Hrs:%02d Mins:%02d\n", ts.months, ts.days, ts.hours, ts.minutes); } catch (Exception e) { e.printStackTrace(); } } }