java– 引发了奇怪的org.threeten.bp.DateTimeException?

java– 引发了奇怪的org.threeten.bp.DateTimeException?,第1张

概述我的代码运行得很好.今天我突然开始得到这个异常–org.threeten.bp.DateTimeException:无法打印字段DayOfMonth,因为值1872095944最大宽度为2这是我的简单代码:LocalDateTimedate=LocalDateTime.now();DateTimeFormatterformatter=DateTimeFormatter.ofPattern("dd

我的代码运行得很好.今天我突然开始得到这个异常 – org.threeten.bp.DateTimeException:无法打印字段DayOfMonth,因为值1872095944最大宽度为2
这是我的简单代码:

@H_403_6@LocalDateTime date = LocalDateTime.Now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd - MM - uuuu"); String sDate = date.format(formatter);//EXCEPTION THROWN HERE

为什么这个问题突然?
编辑
这似乎是一个中间问题.它有时崩溃,其他时候工作正常.没有关于发生了什么的线索.一个

解决方法:

它不是一个格式化问题(这里只是一个症状),而是一个如何创建LocalDateTime实例的问题.根本原因很简单,在一些罕见的情况下,LocalDateTime.Now()似乎会产生一个完全超出界限的日期.这个问题可能与这个问题跟踪器上的这个issue有关.

LocalDate.ofEpochDay(x) sometimes returns a wrong or illegal result
instead of throwing an exception for large values of x . For
instance, LocalDate.ofEpochDay(9223371671611556645L) returns a date
with a negative value for d.getDayOfMonth() instead of throwing a
DateTimeException .

请记住,Now()方法必须在后台执行epoch转换,最后调用LocalDate.ofEpochDay(…).因此,如果你的时钟在Unix纪元以来以毫秒为单位产生一个不寻常的纪元值,那么这也会影响Now().并且您的格式化程序只需通过有效调用getDayOfMonth()(实际上通过TemporalAccessor中的字段访问)从LocalDateTime获取日期.有问题的源代码:

@H_403_6@281 public static LocalDate ofEpochDay(long epochDay) { 282 long zeroDay = epochDay + DAYS_0000_TO_1970; 283 // find the march-based year 284 zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle 285 long adjust = 0; 286 if (zeroDay < 0) { 287 // adjust negative years to positive for calculation 288 long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1; 289 adjust = adjustCycles * 400; 290 zeroDay += -adjustCycles * DAYS_PER_CYCLE; 291 } 292 long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE; 293 long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400); 294 if (doyEst < 0) { 295 // fix estimate 296 yearEst--; 297 doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400); 298 } 299 yearEst += adjust; // reset any negative year 300 int marchDoy0 = (int) doyEst; 301 302 // convert march-based values back to january-based 303 int marchMonth0 = (marchDoy0 * 5 + 2) / 153; 304 int month = (marchMonth0 + 2) % 12 + 1; 305 int dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1; 306 yearEst += marchMonth0 / 10; 307 308 // check year Now we are certain it is correct 309 int year = YEAR.checkValIDIntValue(yearEst); 310 return new LocalDate(year, month, dom); 311 }

最有趣和最可疑的是,只有一年被验证,而不是月份或日期.事实上,看看这个奇怪的结果,包含由减号(???)分隔的四个部分:

@H_403_6@LocalDate d = LocalDate.ofEpochDay(9223371671611556645L);System.out.println(d); // -999999999-02-0-30System.out.println(d.getDayOfMonth()); // -30

很明显,库代码会因某些奇特的时代数而被破坏,这可能是由您的时钟产生的.我也在Java-8中测试了相同的代码,结果相同.

更新:

到目前为止显示的LocalDate.ofEpochDay(long)的原始代码肯定会被破坏,这也是因为没有检查数值/算术溢出的事实.例如:像Long.MAX_VALUE这样的输入会导致表达式epochDay DAYS_0000_TO_1970溢出并将符号更改为负数.类似地,当使用表达式400 * zeroDay时,输入Long.MIN_VALUE最终会溢出.我担心这不是显示代码的唯一问题.为了比较:格里高利算法的正确实现更像是在my own time library.

边注:

在我的库Time4J的帮助下,我已经分析过上面给出的测试输入会产生一年远超出界限,如在threeten-bp中定义的那样(范围是-999999999直到999999999):

@H_403_6@PlainDate date = PlainDate.of(9223371671611556645L, EpochDays.UNIX);// @R_404_4126@.IllegalArgumentException: Year out of range: 25252733927766555

我不太清楚你能做些什么来解决这个问题.

首先肯定要记录你的时钟产生的所有输入,将它们与三十二节的观察到的错误行为联系起来,并做一些研究,为什么你的时钟有时会疯狂.

关于threeten-bp(和Java-8!)中的错误,你可以希望三个bp项目团队很快就能修复它(或者更确切地说是Oracle!).导致问题的输入无论如何都可能是错误的,因此您应该最好地捕获异常并使用时钟错误的额外消息(作为根本原因)记录它.

总结

以上是内存溢出为你收集整理的java – 引发了奇怪的org.threeten.bp.DateTimeException?全部内容,希望文章能够帮你解决java – 引发了奇怪的org.threeten.bp.DateTimeException?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1117256.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存