我觉得有趣的是,Java(或 java.util 库)没有内置函数来计算日期差异。 我想从一个日期中减去另一个日期以获得它们之间经过的时间。 做这个的最好方式是什么?
我知道简单的方法是以毫秒为单位的时间差,然后将其转换为天数。 但是,我想知道这是否适用于所有情况(夏令时等)。
I find it funny that Java (or the java.util library) does not have a built-in function to calculate difference in dates. I want to subtract one date from another to get the elapsed time between them. What is the best way to do this?
I know the simple way is to take the difference of the time in milliseconds and then convert that into days. However, I wanted to know if this works in all cases (with daylight saving, etc.).
发布评论
评论(7)
Java 并没有遗漏太多,如果你看看开源的话:试试 Joda-Time。
Java's not missing much, if you look at open source: try Joda-Time.
如果您的时间源自 UTC 日期,或者它们只是在同一系统上测量的两次调用 System.getCurrentTimeMillis() 之间的差异,您将获得有效的毫秒数作为差异,而与任何时区问题无关。 (这就是为什么一切都应该使用 UTC 作为存储格式——从 UTC-> 本地时间更容易;如果您尝试采用其他方式,那么您需要将本地时区与本地时间一起存储 - - 或者尝试推断它,gack!)
至于将其转换为天数,您应该能够除以 86400000... 需要注意的是,偶尔会出现 闰秒 每隔一年左右。
If your times are derived from UTC dates, or they are just the difference between two calls to System.getCurrentTimeMillis() measured on the same system, you will get a valid number of milliseconds as the difference, independent of any timezone issues. (which is why everything should be using UTC as a storage format -- it's much easier to go from UTC->local time; if you try to go the other way then you need to store the local timezone along with the local time -- or attempt to infer it, gack!)
As for turning this into a number of days, you should just be able to divide by 86400000... with the caveat that there is an occasional leap second every other year or so.
使用 Joda-Time 或 Java 8 中新的 java.time 包。
这两个框架都使用半开放方法,其中开头包含,而结尾独家。 有时记为
[)
。 这通常是定义时间跨度的最佳方法。java.time
Java 8 及更高版本中内置的 java.time 框架有一个
Period
类,用于将时间跨度表示为若干年、若干月和若干天。 但这个类仅限于整天,不表示小时、分钟和秒。请注意,我们指定了一个时区,这对于确定日期至关重要。 例如,巴黎的新一天黎明比 蒙特利尔。
对于全天,则夏令时 (DST) 无关紧要。
如果您想要计算总天数,请使用
ChronoUnit
枚举,其中包括一些计算方法。 请注意,计算返回一个 long。我已询问关于在 java.time 中执行完整的周期,包括小时、分钟、秒。 从 Java 8 开始是不可能的。 建议使用捆绑库的令人惊讶的解决方法stackoverflow.com/users/2491410/meno-hochschild">Meno Hochschild:使用
Duration
类可在 javax.xml.datatype 包。Joda-Time
这是 Joda-Time 2.3 中的一些示例代码。
调用
toString
将为您提供由 ISO 8601< 定义的形式的字符串表示形式/a> 标准,PnYnMnDTnHnMnS
。Use either Joda-Time or the new java.time package in Java 8.
Both frameworks use the Half-Open approach where the beginning is inclusive while the ending is exclusive. Sometimes notated as
[)
. This is generally the best approach for defining spans of time.java.time
The java.time framework built into Java 8 and later has a
Period
class to represent a span of time as a number of years, a number of months, and a number of days. But this class is limited to whole days, no representation of hours, minutes, and seconds.Note that we specify a time zone, crucial for determining a date. For example, a new day dawns earlier in Paris than in Montréal.
For whole days, then Daylight Saving Time (DST) is irrelevant.
If you want a count of total days, use the
ChronoUnit
enum which includes some calculation methods. Notice the calculations return a long.I have asked about doing a full period in java.time, including hours, minutes, seconds. Not possible as of Java 8. A surprising workaround using the bundled libraries was suggested by Meno Hochschild: Use a
Duration
class found in the javax.xml.datatype package.Joda-Time
Here is some example code in Joda-Time 2.3.
Calling
toString
will get you a string representation in the form defined by the ISO 8601 standard,PnYnMnDTnHnMnS
.使用 date4j 库:
With the date4j library:
有一个简单的方法来实现它。 我们可以将 Calendar.add 方法与循环一起使用。
例如如下,
beginDate 和 endDate 之间的减日,代码如下,
玩得开心! @.@
There is simple way to implement it. We can use Calendar.add method with loop.
For example as below,
The minus days between beginDate and endDate, and the code as below,
Have Fun! @.@
我不同意 Java 没有计算日期之间差异的机制的说法。
Java 是为全球使用而设计的。 它的设计使得没有日期的概念,只有“以毫秒为单位的时间”的概念。 对诸如特定约定下特定地点的时间和日期这样的世界时间的任何解释都仅仅是一种预测或观点。
日历类用于将这种绝对时间转换为日期。 如果确实需要,您还可以添加或减去日期部分。 提供两个时间之间组件差异的唯一方法是日历生成和特定。 因此,您可能会说标准库不包含足够智能的公历,我同意它还有一些不足之处。
话虽这么说,这种功能有很多实现,我看到其他人提供了示例。
I disagree with the claim that Java doesn't have a mechanism for calculating the difference between dates.
Java was designed for global use. It was designed so that there isn't a concept of date, there is only a concept of "time in milliseconds". Any interpretation of such a universal time as the time-and-date in a specific location under a specific convention is merely a projection or a view.
The calendar class is used to turn this sort of absolute time into dates. You can also add or subtract date components, if you really need to. The only way to provide a difference in term of components between two times would be Calendar generated and specific. Thus, you could argue that the standard library does not include a smart enough Gregorian Calendar, and I would agree that it leaves some to be desired.
That being said, there are numerous implementations of this kind of functionality, I see others have provided examples.
Java 对日期的实现很差。 如果您发现 Joda-Time 太复杂,请尝试我对开源的一点贡献:
http://calendardate.sourceforge.net/javadoc/index.html
Java's implementation of dates is poor. If you find Joda-Time too complicated, try my little contribution to open source:
http://calendardate.sourceforge.net/javadoc/index.html