Java以这种格式减去两个日期

可能重复:
计算Java中日期的差异
你如何减去Java中的日期?

我正在从字符串解析两个日期,如下所示:

Oct 15, 2012 1:07:13 PM Oct 23, 2012 03:43:34 PM 

我需要做的是找出这两个日期之间的区别,例如:

 Oct 23, 2012 03:43:34 PM - Oct 15, 2012 1:07:13 PM 

= 8天2小时36分21秒

^这是我需要得到的两个日期/时间

我相信我需要解析格式并将其转换为另一种格式,然后减去它们之间的差异并进行数学运算以获得两者之间的天/小时/分钟/秒

与其他回答者试图暗示的相反,计算两个日期之间的差异在标准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(); // ... 

但是这种天真的方法并没有考虑闰年,更不用说夏令时和日期时间的本地特定变化了 。


对于java.util.Calendar方法,您基本上需要在计数器循环中使用Calendar#add()来获取年,月和日的经过值。 这需要适当考虑闰年,夏令时和当地特定的干扰。

首先创建这个辅助方法来消除一些样板代码:

 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的时间是沃尔哈拉。 这是一个具体的启动示例,说明如何使用纯Joda时间完成所有操作:

 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”虽然需要一些工作,但这是不可能的。

您需要使用SimpleDateFormat来解析String并创建Date

然后你可以找到日期之间的差异。

这是SimpleDateFormat的 javadoc

尝试这个:

 Calendar ca1 = Calendar.getInstance(); ca1.set(2012,05,25); // Addition of date in java ca1.add(Calendar.DATE, 23); // Add 23 days in Dates in Calendar ca1.add(Calendar.MONTH, 2); // Add 2 Month in Date in Calendar ca1.add(Calendar.YEAR, 4); // add 4 Year in Date in Calendar ca1.add(Calendar.DATE, -23); // sub 23 days in Dates in Calendar ca1.add(Calendar.MONTH, -2); // sub 2 Month in Date in Calendar ca1.add(Calendar.YEAR, -4); // sub 4 Year in Date in Calendar