17

我觉得 Java(或 java.util 库)没有内置函数来计算日期差异很有趣。我想从另一个日期中减去一个日期以获得它们之间的经过时间。做这个的最好方式是什么?

我知道简单的方法是以毫秒为单位的时间差,然后将其转换为天。但是,我想知道这是否适用于所有情况(夏令时等)。

4

7 回答 7

8

如果您查看开源,Java 并没有丢失太多:试试Joda-Time

于 2009-01-17T14:48:21.050 回答
6

我知道简单的方法是以毫秒为单位的时间差,然后将其转换为天。但是,我想知道这是否适用于所有情况(夏令时等)。

如果您的时间来自 UTC 日期,或者它们只是在同一系统上测量的两次 System.getCurrentTimeMillis() 调用之间的差异,您将获得有效的毫秒数作为差异,与任何时区问题无关。(这就是为什么一切都应该使用 UTC 作为存储格式的原因——从 UTC-> 本地时间开始要容易得多;如果你尝试另一种方式,那么你需要将本地时区与本地时间一起存储——或尝试推断它,gack!)

至于将其转换为天数,您应该只能除以 86400000 ......但需要注意的是每隔一年左右偶尔会有一次闰秒。

于 2009-01-17T15:07:12.430 回答
4

使用 Joda-Time 或 Java 8 中的新 java.time 包。

两个框架都使用半开放方法,其中开头是包容性的,而结尾是独占性的。有时记为[). 这通常是定义时间跨度的最佳方法。

java.time

Java 8 及更高版本中内置的 java.time 框架有一个Period类,用于将时间跨度表示为年数、月数和天数。但是这个类仅限于一整天,没有小时、分钟和秒的表示。

请注意,我们指定了一个时区,这对于确定日期至关重要。例如,巴黎的新一天比蒙特利尔更早。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate now = LocalDate.now( zoneId );
LocalDate then = LocalDate.of( 2001, 1, 1 );
Period period = Period.between( then, now );

然后:2001-01-01。现在:2015-09-07。期间:P14Y8M6D。天数:5362

对于一整天,夏令时 (DST)是无关紧要的。

如果您想要计算总天数,请使用ChronoUnit包含一些计算方法的枚举。请注意,计算返回很长。

long days = ChronoUnit.DAYS.between( then, now );  // "5362" seen above.

我问过在 java.time 中做一个完整的时间,包括小时、分钟、秒。从 Java 8 开始不可能。Meno Hochschild提出了一个使用捆绑库的令人惊讶的解决方法:使用javax.xml.datatype 包中的类。Duration

乔达时间

这是 Joda-Time 2.3 中的一些示例代码。

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime start = new DateTime( 2014, 1, 2, 3, 4, 5, timeZone );
DateTime stop = new DateTime( 2014, 5, 2, 3, 4, 5, timeZone );
Period period = new Period( start, stop );

调用将为您提供ISO 8601标准toString定义的形式的字符串表示, .PnYnMnDTnHnMnS

于 2014-06-03T07:05:11.623 回答
2

使用date4j库:

int numDaysBetween = oneDate.numDaysFrom(anotherDate);
于 2011-02-13T02:14:40.497 回答
1

有一种简单的方法来实现它。我们可以使用带有循环的 Calendar.add 方法。例如如下,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

Date beginDate = dateFormat.parse("2013-11-29");
Date endDate = dateFormat.parse("2013-12-4");

Calendar beginCalendar = Calendar.getInstance();
beginCalendar.setTime(beginDate);

Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);

beginDate 和 endDate 之间的减号天数,代码如下,

int minusDays = 0;
while (true) {
  minusDays++;

  // Day increasing by 1
  beginCalendar.add(Calendar.DAY_OF_MONTH, 1);

  if (dateFormat.format(beginCalendar.getTime()).
            equals(dateFormat.format(endCalendar).getTime())) {
    break;
  }
}
System.out.println("The substractation between two days is " + (minusDays + 1));

玩得开心!@.@

于 2013-12-04T12:34:04.770 回答
0

Java 的日期实现很差。如果你觉得Joda-Time太复杂,试试我对开源的一点贡献:http: //calendardate.sourceforge.net/javadoc/index.html

于 2009-01-19T21:58:54.293 回答
0

我不同意 Java 没有计算日期之间差异的机制的说法。

Java 是为全球使用而设计的。它被设计成没有日期的概念,只有“以毫秒为单位的时间”的概念。在特定约定下,对特定地点的时间和日期这样的世界时间的任何解释都只是一种投影或一种看法。

日历类用于将这种绝对时间转换为日期。如果确实需要,您还可以添加或减去日期组件。在两次之间提供组件术语差异的唯一方法是日历生成和特定。因此,您可能会争辩说标准库不包含足够智能的公历,我同意它还有一些不足之处。

话虽如此,这种功能有很多实现,我看到其他人提供了示例。

于 2009-01-19T22:06:20.613 回答