Java 9答案:Duration.toXxxPart方法
基本想法,不完整:
Duration dur = Duration.between(ago,now);
this.seconds = dur.toSecondsPart(); // 40
this.minutes = dur.toMinutesPart(); // 41
this.hours = dur.toHoursPart(); // 1
this.days = dur.toDaysPart(); // 0
经过测试,与您的问题相距6100秒。 toXxxPart
方法是Java 9中引入的。对于Java 8(或ThreeTen Backport),您需要从较粗的单位(天)开始,并从持续时间中减去它们,然后再得到下一个较细的单位。有关示例,请参见this answer by lauhub
但是,要完全正确,年和日有些棘手。要仅获取超过整年的日期,请使用完整的代码:
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime agoZdt = ago.atZone(zone);
ZonedDateTime nowZdt = now.atZone(zone);
this.years = ChronoUnit.YEARS.between(agoZdt,nowZdt);
ZonedDateTime afterWholeYears = agoZdt.plusYears(this.years);
Duration dur = Duration.between(afterWholeYears,nowZdt);
this.seconds = dur.toSecondsPart(); // 40
this.minutes = dur.toMinutesPart(); // 41
this.hours = dur.toHoursPart(); // 1
this.days = dur.toDays(); // 0
我故意只读ZoneId.systemDefault()
一次,以防万一有人更改正在进行的默认时区设置。
,
类似的事情应该起作用:
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime ago = ZonedDateTime.ofInstant(Instant.ofEpochSeconds(unixSeconds),zone);
ZonedDateTime now = ZonedDateTime.now(zone);
Period period = Period.between(ago.toLocalDate(),now.toLocalDate());
ZonedDateTime adjusted = ago.with(now.toLocalDate());
if (adjusted.isAfter(now)) {
adjusted = adjusted.minusDays(1);
period = period.minusDays(1);
}
Duration duration = Duration.between(adjusted,now);
assert duration.toDaysPart() == 0;
years = period.getYears();
months = period.getMonths();
days = period.getDays();
hours = duration.toHoursPart();
minutes = duration.toMinutesPart();
seconds = duration.toSecondsPart();
为什么/如何工作:
- 通过使用专门的
Period
类型来计算非时间字段(年,月,日)之间的差异,该类型正是为此目的而设计的。它使用两个日期时间的LocalDate
部分,这是安全的,因为它们都在同一时区
- 要了解其余字段的差异,我们调整了“
ago
”值,以使日期完全相同。如果我们碰巧超调了(如果“ ago”发生在本地时间早于“ now”,那么可能会发生),我们通过将调整后的日期时间和期间都减少一天来进行调整
- 然后,我们使用
Duration
类来获取基于时间的字段之间的差异。由于在那里我们查询了调整后的日期时间之间的差异,因此我们的持续时间不会超过一天,为此我添加了断言。
- 最后,我在
Period
和Duration
上使用了各种可用的方法来获取其“字段”。请注意,我使用的Duration
类方法自Java 9起才可用,因此,如果您还没有,就必须使用toMinutes()
之类的方法,并手动将它们除以数量,例如每小时的分钟数,例如:
// those constants you'll have to define on your own,shouldn't be hard
hours = duration.toHours() % Constants.HOURS_PER_DAY;
或者,如果您不想定义常量,则可以通过调整“ ago”变量来重复该技巧:
adjusted = ago.with(now.toLocalDate());
if (adjusted.isAfter(now)) {
adjusted = adjusted.minusDays(1);
period = period.minusDays(1);
}
hours = HOURS.between(adjusted,now);
adjusted = adjusted.withHour(now.getHour());
if (adjusted.isAfter(now)) {
adjusted = adjusted.minusHour(1);
hours -= 1;
}
minutes = MINUTES.between(adjusted,now);
adjusted = adjusted.withMinute(now.getMinute());
if (adjusted.isAfter(now)) {
adjusted = adjusted.minusMinutes(1);
minutes -= 1;
}
seconds = SECONDS.between(adjusted,now);
本文链接:https://www.f2er.com/3149864.html