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

标签 java

<分区>

Possible Duplicate:
Calculating difference in dates in Java
How do you subtract Dates in 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();
// ...

但是这种天真的方法没有考虑闰年,更不用说夏令时和local-specific changes in datetime了。 .


至于 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 time瓦尔哈拉。这是一个具体的启动示例,说明如何使用纯 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”虽然需要一些工作,但那不是问题。

关于Java以这种格式减去两个日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13036907/

相关文章:

java - Spring WebSecurity允​​许从url访问

java - Math.random if语句错误

Java 使用 radioButton 处理图像

java - 编辑cordova制作的java文件以访问Android中的GPS传感器

java - 扩展 Eclipse 调试功能

java - 如何使用 Java、tomcat、eclipse 在 Restful web 服务中调用这么多的 Json 数据

java - Angelika Langer Enum<E extends Enum<E>> 解码

java - java中使用正则表达式获取数据

java - 如果我们将空键添加为对象,为什么同步对象会给出空指针异常?

java - 如何修复 Veracode CWE 117(日志输出中和不当)