2009-01-17 102 views
17

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

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

+2

有关某些背景,请参阅http://www.xmission.com/~goodhill/dates/deltaDates.html。 – 2009-01-17 15:24:25

+0

这是一篇不错的文章。谢谢! – Anirudh 2009-01-18 08:43:16

+0

@Anirudh搜索StackOverflow中的“joda”和术语,如“span”,“Interval”,“Duration”,“Period”。你会发现许多讨论的例子。 – 2014-03-19 17:13:32

回答

6

我知道简单的方法就是采取的时间 差以毫秒为单位 和再转化天。 但是,我想知道这个 是否适用于所有情况(与日光 保存等)。

如果你的时间是从UTC日期衍生,或者他们只是两个电话之间在同一系统上测量System.getCurrentTimeMillis()的区别,你会得到毫秒的差别的有效号码,独立的任何时区问题。 (这就是为什么一切应该使用UTC作为存储格式 - 从UTC->当地时间更容易;如果您尝试以其他方式进行,那么您需要将本地时区和本地时间一起存储 - 或试图推断它,gack!)

至于把这个变成了几天,你应该能够除以86400000 ...与警告,偶尔leap second每隔一年左右。

8

如果你看开源的话,Java的不会错过太多:尝试Joda-Time

+3

关于Java日期的问题==>回答提及乔达! – 2009-01-17 14:57:57

0

我与Java没有一个机制来计算日期之间的差值的要求不以为然。

Java是为全球使用而设计的。它的设计使得没有日期的概念,只有“毫秒时间”的概念。在特定的约定下,对某个特定地点的时间和日期等世界时间的任何解释都只是一个预测或一个观点。

日历类用于将这种绝对时间变成日期。如果您真的需要,也可以添加或减去日期组件。在两次之间提供组件之间的差异的唯一方法是日历生成和特定。因此,你可能会争辩说,标准库不包括一个足够聪明的公历,我同意它留下一些需要。

这就是说,这种功能有很多的实现,我看到其他人提供的例子。

2

随着date4j库:

int numDaysBetween = oneDate.numDaysFrom(anotherDate); 
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日期和结束日期,和下面的代码之间的负天,

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)); 

玩得开心! @。@

4

二者必选其一乔达时间或新java.time包中的Java 8

两个框架使用半开方法,即最开始是包容而结局是独家。有时标注为[)。这通常是定义跨度时间的最佳方法。

java.time

的java.time框架构建在Java 8,后来有一个Period类来表示的时间跨度数年,数月,和天数。但是这堂课只限于整整一天,没有小时,分钟和秒的表示。

请注意,我们指定一个时区,这对决定日期至关重要。例如,Paris之前的新的一天早于Montréal

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

对于整个日子,然后Daylight Saving Time (DST)是无关紧要的。

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

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

I have asked大约在java.time做了充分的时间段,包括小时,分钟,秒。在Java 8中不可能。使用捆绑的库was suggestedMeno Hochschild)的一个令人惊讶的解决方法:使用javax.xml.datatype package中的Duration类。

约达时间

以下是在约达时间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); 

调用toString将让你在由ISO 8601标准,PnYnMnDTnHnMnS规定的形式的字符串表示。