java两个字符串 相隔天数_关于Java: Joda-Time时间中两个日期之间的天数

我如何找到两个joda time DateTime实例之间的天数差异?如果开始时间是星期一,结束时间是星期二,那么不管开始和结束日期的小时/分钟/秒是多少,返回值都应该是1。

如果从晚上开始到早上结束,Days.daysBetween(start, end).getDays()给我0。

我对其他日期字段也有同样的问题,所以我希望有一种通用的方法来"忽略"那些意义较小的字段。

换句话说,2月和3月4日之间的月份也是1,14:45到15:12之间的时间也是1。但是14:01和14:55之间的小时差为0。

令人恼火的是,withTimeatStartofDay的答案是错误的,但只是偶尔。你想要:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

事实证明,"午夜/一天的开始"有时意味着凌晨1点(日光节约在某些地方是这样发生的),而白天之间的时间处理得不好。

// 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

通过LocalDate避开了整个问题。

您能否提供一个示例案例,其中包含您认为Days.daysBetween不正确的特定数据?

@巴兹堡-我的答案中已经有了这个例子。

当你说要使用Instant时,你不仅仅是在谈论start.toInstant(),是吗?

@帕特里克是的,我是。经过深思熟虑,我们还不清楚这到底是要施加什么约束,所以我将删除最后一句话。谢谢!

@Chrispy Daysbetween医生说它返回整天的数据。在我的情况下,2天1小时应该可以让我返回3天。在您的示例中,它返回2天。有没有办法做到这一点?

@苏吉乔希,恐怕我不明白你的问题。我建议发布一个完整的堆栈溢出问题并为我粘贴一个链接:)

注意日期与新年重叠!2016年12月31日至2017年1月5日之间的天数为-361天。

@西尔夫,不,不,我刚检查过。我怀疑你2017年打字错误。

Days类

使用Days类和withTimeAtStartOfDay方法应该可以:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()

谢谢!我试图用joda实现android.text.format.dateutils.getrelativeTimespanstring()的行为,这非常有用。

先生,关于本文,不推荐使用来自日期时间类型的方法toDateMidnight()。

现在应该使用.withTimeAtStartOfDay()而不是.todateMidnight()。

如果end在start之前,它是否返回负天数?

@阿凯亚:你为什么不试试呢?

您可以使用LocalDate:

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()

先生,关于本文,不推荐使用来自日期时间类型的方法toDateMidnight()。

更新…

为什么用new LocalDate(date)代替date.toLocalDate()?

DR

java.time.temporal.ChronoUnit.DAYS.between(

earlier.truncatedTo( ChronoUnit.DAYS )  ,

later.truncatedTo( ChronoUnit.DAYS )

)

…或…

java.time.temporal.ChronoUnit.HOURS.between(

earlier.truncatedTo( ChronoUnit.HOURS )  ,

later.truncatedTo( ChronoUnit.HOURS )

)

Java.时间

仅供参考,Joda Time项目现在处于维护模式,团队建议迁移到java.time类。

与joda时间DateTime相当的是ZonedDateTime。

ZoneId z = ZoneId.of("Pacific/Auckland" ) ;

ZonedDateTime now = ZonedDateTime.now( z ) ;

显然,你想按日期数日,这意味着你想忽略一天中的时间。例如,从午夜前的一分钟开始到午夜后的一分钟结束应该会导致一天。对于这种行为,从您的ZonedDateTime中提取一个LocalDate。LocalDate类表示没有时间和时区的仅日期值。

LocalDate localDateStart = zdtStart.toLocalDate() ;

LocalDate localDateStop = zdtStop.toLocalDate() ;

使用ChronoUnit枚举计算经过的天数或其他单位。

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

截断

至于你想问一个更一般的方法来做这个计数,如果你感兴趣的是小时的增量作为时钟的小时,而不是完整的小时作为60分钟的时间跨度,使用truncatedTo方法。

这是你在同一天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

按日期计算的天数,截断为ChronoUnit.DAYS。这里有一个例子,在1过去的几天里,午夜从5分钟前滚动到5分钟后。

ZoneId z = ZoneId.of("America/Montreal" );

ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 23 , 55 , 0 , 0 , z );

ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 18 , 00 , 05 , 0 , 0 , z );

long days = ChronoUnit.DAYS.between( start.truncatedTo( ChronoUnit.DAYS ) , stop.truncatedTo( ChronoUnit.DAYS ) );

1

关于JavaTimes

JavaTimeFr框架是在Java 8和之后构建的。这些类取代了麻烦的旧遗留日期时间类,如java.util.Date、Calendar和SimpleDateFormat。

现在处于维护模式的joda time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程。以及搜索堆栈溢出以获得许多示例和解释。规格为JSR 310。

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

Java SE 8、Java SE 9、Java SE 10以及以后

内置的。

标准JAVA API的一部分与捆绑实现。

Java 9添加了一些小的特性和修复。

Java SE 6和Java SE 7

大部分JavaTimeActudio都被移植到TealEnter后端的Java 6和7中。

安卓

java.time类的Android包实现的更高版本。

对于早期的Android(<26),threetenabp项目适应threeten backport(如上所述)。看看如何使用三连珠……

threeten额外项目使用额外的类扩展java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,如Interval、YearWeek、YearQuarter等等。

threeten额外项目使用额外的类扩展java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,如Interval、YearWeek、YearQuarter等等。

接受的答案构建了两个LocalDate对象,如果您正在读取大量数据,这是非常昂贵的。我用这个:

public static int getDaysBetween(DateTime earlier, DateTime later)

{

return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());

}

通过调用getMillis()可以使用已经存在的变量。那么,MILLISECONDS.toDays()使用简单的算术计算,不创建任何对象。

只有当您对"天"的定义正好是24小时,而不考虑时区和日期时,此答案才有效。如果是这样,使用这种方法。如果没有,请查看其他解决时区问题的答案。

@巴兹尔布尔克,你说得对,不过,我还是想找一个基于算术计算的解决方案,而不是为每个方法调用构建昂贵的对象,这样的计算有很多味道,如果你正在从网页中读取输入,可能没问题,但是如果你正在处理一个有数十万行的日志文件只是让它很慢

如果循环是热的,Java将优化对象分配。见docs.oracle.com/javase/7/docs/technotes/guides/vm/&hellip;

java.time.Period

使用java.time.Period类计算天数。

由于Java 8计算的差异更直观,使用EDCOX1,0,EDCOX1,30表示两个日期。

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

DateTime  dt  = new DateTime(laterDate);

DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());

System.out.println("No of days :" + newDate.getDayOfYear() - 1 );

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;

}

这个问题是专门寻找乔达的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值