与其他回答者试图暗示的相反,在标准Java SE中,计算两个日期之间的差异并不是那么简单。
您的第一步确实是将这些字符串转换为可用
Date实例。您可以使用进行此操作
SimpleDateFormat。这是一个启动示例:
String string1 = "Oct 15, 2012 1:07:13 PM";String string2 = "Oct 23, 2012 03:43:34 PM";SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy h:mm:ss a", Locale.ENGLISH);Date date1 = sdf.parse(string1);Date date2 = sdf.parse(string2);(请注意Locale
此处可选参数的重要性,在有关将字符串转换为日期的答案中常常忽略了这一点)
下一步是计算这两个日期之间的差。当您仅限于标准Java SE
API时,这是一项艰巨的任务。最好的是您可以得到的
java.util.Calendar。
请注意,您当然可以减去毫秒,然后使用常规算术运算符计算差值。
long differenceInMillis = date2.getTime() - date1.getTime();// ...
但是,这种幼稚的方法没有考虑leap年,更不用说夏时制和日期时间的本地特定更改了。
对于该
java.util.Calendar方法,您 基本上
需要
Calendar#add()在计数器循环中使用以获取数年,数月和数天的经过值。这需要适当考虑leap年,夏时制和当地时间的干扰。
首先创建此帮助程序方法以消除一些样板代码:
public static int elapsed(Calendar before, Calendar after, int field) { Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected. int elapsed = -1; while (!clone.after(after)) { clone.add(field, 1); elapsed++; } return elapsed;}现在,您可以计算出经过时间,如下所示:
Calendar start = Calendar.getInstance();start.setTime(date1);Calendar end = Calendar.getInstance();end.setTime(date2);Integer[] elapsed = new Integer[6];Calendar clone = (Calendar) start.clone(); // Otherwise changes are been reflected.elapsed[0] = elapsed(clone, end, Calendar.YEAR);clone.add(Calendar.YEAR, elapsed[0]);elapsed[1] = elapsed(clone, end, Calendar.MONTH);clone.add(Calendar.MONTH, elapsed[1]);elapsed[2] = elapsed(clone, end, Calendar.DATE);clone.add(Calendar.DATE, elapsed[2]);elapsed[3] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 3600000;clone.add(Calendar.HOUR, elapsed[3]);elapsed[4] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 60000;clone.add(Calendar.MINUTE, elapsed[4]);elapsed[5] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 1000;System.out.format("%d years, %d months, %d days, %d hours, %d minutes, %d seconds", elapsed);是的,非常难看。
如果您打算经常用Java处理日期和时间,那么您可能会发现Joda time是walhalla。这是一个具体的启动示例,说明如何使用纯Joda Time来完成所有操作:
String string1 = "Oct 15, 2012 1:07:13 PM";String string2 = "Oct 23, 2012 03:43:34 PM";DateTimeFormatter dtf = DateTimeFormat.forPattern("MMM d, yyyy h:mm:ss a").withLocale(Locale.ENGLISH);DateTime dateTime1 = dtf.parseDateTime(string1);DateTime dateTime2 = dtf.parseDateTime(string2);Period period = new Period(dateTime1, dateTime2);PeriodFormatter formatter = new PeriodFormatterBuilder() .appendYears().appendSuffix(" years ") .appendMonths().appendSuffix(" months ") .appendWeeks().appendSuffix(" weeks ") .appendDays().appendSuffix(" days ") .appendHours().appendSuffix(" hours ") .appendMinutes().appendSuffix(" minutes ") .appendSeconds().appendSuffix(" seconds ") .printZeronever() .toFormatter();String elapsed = formatter.print(period);System.out.println(elapsed);好多了吧?复数形式的“ s”虽然需要一些工作,但这是不可能的。



