我有个很久以前的约会。
我发现了从这个日期到现在的持续时间。
现在我想知道-这几年是多少钱?
我想出了这个使用Java8 API的解决方案。
这是一个可怕的解决方案,因为我必须首先手动将持续时间转换为天,因为否则就会有一个UnsupportedTemporalTypeException
--无论出于什么原因,都不支持LocalDate.plus(SECONDS)
。
即使编译器允许此调用。
是否有较少冗长的可能性将Duration
转换为年份?
LocalDate dateOne = LocalDate.of(1415, Month.JULY, 6);
Duration durationSinceGuss1 = Duration.between(LocalDateTime.of(dateOne, LocalTime.MIDNIGHT),LocalDateTime.now());
long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(),
LocalDate.now().plus(
TimeUnit.SECONDS.toDays(
durationSinceGuss1.getSeconds()),
ChronoUnit.DAYS) );
/*
* ERROR -
* LocalDate.now().plus(durationSinceGuss1) causes an Exception.
* Seconds are not Supported for LocalDate.plus()!!!
* WHY OR WHY CAN'T JAVA DO WHAT COMPILER ALLOWS ME TO DO?
*/
//long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(), LocalDate.now().plus(durationSinceGuss) );
/*
* ERROR -
* Still an exception!
* Even on explicitly converting duration to seconds.
* Everything like above. Seconds are just not allowed. Have to convert them manually first e.g. to Days?!
* WHY OR WHY CAN'T YOU CONVERT SECONDS TO DAYS OR SOMETHING AUTOMATICALLY, JAVA?
*/
//long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(), LocalDate.now().plus(durationSinceGuss.getSeconds(), ChronoUnit.SECONDS) );
发布于 2016-02-03 16:09:15
你试过使用LocalDateTime
或DateTime
而不是LocalDate
吗?根据设计,后者不支持小时/分钟/秒/等,因此,当您尝试向其添加秒时,就会出现UnsupportedTemporalTypeException
。
例如,这起作用是:
LocalDateTime dateOne = LocalDateTime.of(1415, Month.JULY, 6, 0, 0);
Duration durationSinceGuss1 = Duration.between(dateOne, LocalDateTime.now());
long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDateTime.now(), LocalDateTime.now().plus(durationSinceGuss1) );
System.out.println(yearsSinceGuss); // prints 600
发布于 2016-02-03 16:11:28
使用Period
获取两个LocalDate
对象之间的年数:
LocalDate before = LocalDate.of(1415, Month.JULY, 6);
LocalDate now = LocalDate.now();
Period period = Period.between(before, now);
int yearsPassed = period.getYears();
System.out.println(yearsPassed);
发布于 2016-02-04 02:38:21
虽然@Matt Ball的公认答案试图在使用Java-8-API方面变得聪明,但我还是会提出以下反对意见:
您的需求并不准确,因为无法将秒精确转换为年数。
原因如下:
也许对你的代码最重要的异议是:
我无法想象1415年这一日期的供应商打算把这样的日期解释为公历日期.
我理解从秒到年份的转换的愿望,但是无论您选择什么作为解决方案,只能是一个近似的。所以,如果你有1415年这样的时间,我建议你做一个非常简单的近似:
Duration d = ...;
int approximateYears = (int) (d.toDays() / 365.2425);
对我来说,只要我们真的想为这样的用例使用基于第二的持续时间,在历史背景下就足够了。似乎您无法更改从外部来源获得的输入(否则,最好与持续时间供应商联系,并询问是否可以提供天数)。不管怎么说,你必须问问自己你想申请什么样的年份定义。
边注:
你的抱怨“为什么或者为什么JAVA不能做编译器允许我做的事情?”与新java.time-API的字符不匹配。
您希望API是类型安全的,但是java.time
(JSR-310)不是设计为类型安全的,严重依赖于运行时异常。编译器将不会帮助您使用此API。相反,如果任何给定的时间单位适用于任何给定的时间类型,则您必须查阅文档。您可以在Temporal.isSupported(TemporalUnit)的任何具体实现的文档中找到这样的答案。无论如何,编译安全的愿望是可以理解的(我已经尽了最大努力将我自己的时间库Time4J实现为类型安全),但是JSR-310的设计已经是一成不变的了。
如果您将java.time.Duration
应用于LocalDateTime
或Instant
,也会有一个小缺陷,因为结果并不完全可比较(第一种类型的秒是在本地时间线上定义的,而Instant
的秒是在全局时间线上定义的)。因此,即使没有运行时异常,如@Matt的公认答案,我们也必须仔细考虑这种计算的结果是否合理和可信。
https://stackoverflow.com/questions/35190184
复制相似问题