Java Joda-Time 中两个日期之间的天数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3802893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Number of days between two dates in Joda-Time
提问by pvgoddijn
How do I find the difference in Days between two Joda-TimeDateTime
instances?
With ‘difference in days' I mean if start is on Monday and end is on Tuesday I expect a return value of 1 regardless of the hour/minute/seconds of the start and end dates.
如何找到两个Joda-TimeDateTime
实例之间的天数差异?对于“天数差异”,我的意思是如果开始是星期一,结束是星期二,我希望返回值为 1,而不管开始日期和结束日期的小时/分钟/秒。
Days.daysBetween(start, end).getDays()
gives me 0 if start is in the evening and end in the morning.
Days.daysBetween(start, end).getDays()
如果开始在晚上并在早上结束,则给我 0。
I'm also having the same issue with other date fields so I was hoping there would be a generic way to 'ignore' the fields of lesser significance.
我对其他日期字段也有同样的问题,所以我希望有一种通用的方法来“忽略”重要性较低的字段。
In other words, the months between Feb and 4 March would also be 1, as would the hours between 14:45 and 15:12 be. However the hour difference between 14:01 and 14:55 would be 0.
换句话说,2 月和 3 月 4 日之间的月份也将是 1,14:45 和 15:12 之间的小时也是如此。但是,14:01 和 14:55 之间的小时差将为 0。
采纳答案by Alice Purcell
Annoyingly, the withTimeAtStartOfDay answer is wrong, but only occasionally. You want:
恼人的是, withTimeAtStartOfDay 答案是错误的,但只是偶尔。你要:
Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()
It turns out that "midnight/start of day" sometimes means 1am (daylight savings happen this way in some places), which Days.daysBetween doesn't handle properly.
事实证明,“午夜/一天的开始”有时意味着凌晨 1 点(夏令时在某些地方以这种方式发生),而 Days.daysBetween 无法正确处理。
// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
end.toLocalDate()).getDays());
// prints 1
Going via a LocalDate
sidesteps the whole issue.
通过走出去LocalDate
回避了整个问题。
回答by Bozho
回答by Michael Borgwardt
Days
Class
Days
班级
Using the Days
class with the withTimeAtStartOfDay
method should work:
将Days
类与withTimeAtStartOfDay
方法一起使用应该可以:
Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()
回答by user1091978
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
final int SECONDS = 60;
final int MINUTES = 60;
final int HOURS = 24;
final int MILLIES = 1000;
long temp;
if (timestamp1 < timestamp2) {
temp = timestamp1;
timestamp1 = timestamp2;
timestamp2 = temp;
}
Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
endDate.setTimeInMillis(timestamp1);
startDate.setTimeInMillis(timestamp2);
if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
int day1 = endDate.get(Calendar.DAY_OF_MONTH);
int day2 = startDate.get(Calendar.DAY_OF_MONTH);
if (day1 == day2) {
return 0;
} else {
return 1;
}
}
int diffDays = 0;
startDate.add(Calendar.DAY_OF_MONTH, diffDays);
while (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
diffDays++;
}
return diffDays;
}
回答by JBoy
The accepted answer builds two LocalDate
objects, which are quite expensive if you are reading lot of data.
I use this:
接受的答案构建了两个LocalDate
对象,如果您正在阅读大量数据,这将非常昂贵。我用这个:
public static int getDaysBetween(DateTime earlier, DateTime later)
{
return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
}
By calling getMillis()
you use already existing variables.MILLISECONDS.toDays()
then, uses a simple arithmetic calculation, does not create any object.
通过调用getMillis()
您使用已经存在的变量。MILLISECONDS.toDays()
然后,使用简单的算术计算,不创建任何对象。
回答by Basil Bourque
tl;dr
tl;博士
java.time.temporal.ChronoUnit.DAYS.between(
earlier.toLocalDate(),
later.toLocalDate()
)
…or…
…或者…
java.time.temporal.ChronoUnit.HOURS.between(
earlier.truncatedTo( ChronoUnit.HOURS ) ,
later.truncatedTo( ChronoUnit.HOURS )
)
java.time
时间
FYI, the Joda-Timeproject is now in maintenance mode, with the team advising migration to the java.timeclasses.
仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。
The equivalent of Joda-Time DateTime
is ZonedDateTime
.
Joda-Time 的等价物DateTime
是ZonedDateTime
.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Apparently you want to count the days by dates, meaning you want to ignore the time of day. For example, starting a minute before midnight and ending a minute after midnight should result in a single day. For this behavior, extract a LocalDate
from your ZonedDateTime
. The LocalDate
class represents a date-only value without time-of-day and without time zone.
显然您想按日期计算天数,这意味着您想忽略一天中的时间。例如,从午夜前一分钟开始到午夜后一分钟结束应该是一天。对于此行为,请LocalDate
从您的ZonedDateTime
. 该LocalDate
级表示没有时间一天和不同时区的日期,唯一的价值。
LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;
Use the ChronoUnit
enum to calculate elapsed days or other units.
使用ChronoUnit
枚举来计算经过的天数或其他单位。
long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;
Truncate
截短
As for you asking about a more general way to do this counting where you are interested the delta of hours as hour-of-the-clock rather than complete hours as spans-of-time of sixty minutes, use the truncatedTo
method.
至于您询问更通用的方法来进行此计数,其中您对小时的增量感兴趣,而不是完整的小时作为 60 分钟的时间跨度,请使用该truncatedTo
方法。
Here is your example of 14:45 to 15:12 on same day.
这是您在同一天 14:45 到 15:12 的示例。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );
long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );
1
1
This does not work for days.Use toLocalDate() in this case.
这几天不起作用。在这种情况下使用 toLocalDate()。
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- java.time 类的更高版本的 Android 捆绑实现。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Arnab Bhui
DateTime dt = new DateTime(laterDate);
DateTime newDate = dt.minus( new DateTime ( previousDate ).getMillis());
System.out.println("No of days : " + newDate.getDayOfYear() - 1 );
回答by AzizSM
java.time.Period
java.time.Period
Use the java.time.Period
class to count days.
使用java.time.Period
类来计算天数。
Since Java 8 calculating the difference is more intuitive using LocalDate
, LocalDateTime
to represent the two dates
由于 Java 8 计算差异更直观,使用LocalDate
,LocalDateTime
来表示两个日期
LocalDate now = LocalDate.now();
LocalDate inputDate = LocalDate.of(2018, 11, 28);
Period period = Period.between( inputDate, now);
int diff = period.getDays();
System.out.println("diff = " + diff);