Java在此格式中减去两个日期

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秒 ^这就是我在两次约会中需要得到的 我认为我需要解析该格式并将其转换为另一种格式,然后减去两者之间的差值并进行数学运算,得到两者之间的日/时/分/秒您需要使用Sim

可能重复:

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

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秒

^这就是我在两次约会中需要得到的


我认为我需要解析该格式并将其转换为另一种格式,然后减去两者之间的差值并进行数学运算,得到两者之间的日/时/分/秒

您需要使用
SimpleDateFormat
解析字符串并创建
日期

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

这里是javadoc for

试试这个:

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

与其他回答者试图暗示的相反,在标准JavaSE中计算两个日期之间的差异并不是那么简单

您的第一步实际上是将这些字符串转换为可用的
Date
实例。您可以使用。以下是一个启动示例:

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
参数的重要性,这在关于将字符串转换为日期的回答中经常被忽略)

下一步是计算这两个日期之间的差异。当您仅限于标准JavaSEAPI时,这是一项糟糕的工作。你能得到的最好的东西是


请注意,您当然可以使用常用的算术运算符减去毫秒并计算差值

但这种天真的方法并没有考虑闰年,更不用说夏令时和时间了


至于
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处理日期和时间,那么您可能会发现walhalla。下面是一个具体的启动示例,说明如何使用纯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”需要做一些工作,但这是不可能的。

上面的副本仅在与组合使用时有效,以便首先将
字符串
转换为
日期
。你可能也想看看乔达的时间:使用这正是我需要的,非常棒。但这是一个小问题。如果一年大于10000,它会影响计算速度,因为
public static int appeased(日历之前、日历之后、int字段)中的循环函数。我试图在不循环的情况下从目标年份减去当前年份,结果是不可预测的。我该怎么做才能在不降低处理速度的情况下处理超过10000年的数据?
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);