gpt4 book ai didi

java - DateTimeParseException : fails on one host, 适用于另一个相同的 JDK

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:05:11 25 4
gpt4 key购买 nike

我真的很困惑。我在本地和生产主机上都在使用 OpenJdk 11.0.3。一个解析日期,一个不解析。关于可能导致差异的任何想法?

编辑:末尾提到的 hacky work around

相同的 JDK:

kesselc:~/openjdk-11.0.3+7/bin$ ./java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment 18.9 (build 11.0.3+7)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7, mixed mode)

prodhost: # java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing)

不同的结果:

kesselc:$ ~/openjdk-11.0.3+7/bin/java DateTest
2019-07-10T09:48-06:00[America/Denver]

prodhost: # java DateTest
Exception in thread "main" java.time.format.DateTimeParseException: Text '948 AM MDT Wed Jul 10 2019' could not be parsed: null
at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2017)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:598)
at DateTest.main(DateTest.java:13)
Caused by: java.lang.NullPointerException
at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.prefixLength(DateTimeFormatterBuilder.java:4527)
at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.add0(DateTimeFormatterBuilder.java:4396)
at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.add(DateTimeFormatterBuilder.java:4391)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.getTree(DateTimeFormatterBuilder.java:4138)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneIdPrinterParser.parse(DateTimeFormatterBuilder.java:4249)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.parse(DateTimeFormatterBuilder.java:2370)
at java.base/java.time.format.DateTimeFormatter.parseUnresolved0(DateTimeFormatter.java:2107)
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2036)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
... 2 more

这是我在两者上运行的简单测试类:

public class DateTest {
private static final DateTimeFormatter hhmm_a_zzz_EEE_MMM_dd_yyyy = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("hmm a zzz EEE MMM d yyyy")
.toFormatter();

public static void main(String[] args) {
System.out.println(ZonedDateTime.parse("948 AM MDT Wed Jul 10 2019", hhmm_a_zzz_EEE_MMM_dd_yyyy));
}
}

编辑:某种程度上是我的解决方案。在这种情况下,我正在解析专门以美国为中心的 NOAA 预测。因此,我破解了自己的 ZoneId.of("MDT") 等价物,以映射到此处记录的 17 个时区的偏移量:https://www.timetemperature.com/abbreviations/united_states_time_zone_abbreviations.shtml

我隐约感到肮脏和羞愧,但这个特定的日期解析器是特定于这个特定来源的,所以我会称之为足够好。

我仍然不知道为什么这两个系统的行为不同,但现在问题已经无关紧要了。

这是两个系统上的 System.getProperties 转储。

好(kesselc):

{sun.desktop=gnome, awt.toolkit=sun.awt.X11.XToolkit, java.specification.version=11, sun.cpu.isalist=, sun.jnu.encoding=UTF-8, java.class.path=., java.vm.vendor=Oracle Corporation, sun.arch.data.model=64, java.vendor.url=http://java.oracle.com/, user.timezone=, os.name=Linux, java.vm.specification.version=11, sun.java.launcher=SUN_STANDARD, user.country=US, sun.boot.library.path=/home/kesselc/.sdkman/candidates/java/11.0.2-open/lib, sun.java.command=DateTest, jdk.debug=release, sun.cpu.endian=little, user.home=/home/kesselc, user.language=en, java.specification.vendor=Oracle Corporation, java.version.date=2019-01-15, java.home=/home/kesselc/.sdkman/candidates/java/11.0.2-open, file.separator=/, java.vm.compressedOopsMode=Zero based, line.separator= , java.specification.name=Java Platform API Specification, java.vm.specification.vendor=Oracle Corporation, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, java.runtime.version=11.0.2+9, user.name=kesselc, path.separator=:, os.version=4.4.0-154-generic, java.runtime.name=OpenJDK Runtime Environment, file.encoding=UTF-8, java.vm.name=OpenJDK 64-Bit Server VM, java.vendor.version=18.9, java.vendor.url.bug=http://bugreport.java.com/bugreport/, java.io.tmpdir=/tmp, java.version=11.0.2, user.dir=/home/kesselc/Projects/flex/weather/out/production/classes, os.arch=amd64, java.vm.specification.name=Java Virtual Machine Specification, java.awt.printerjob=sun.print.PSPrinterJob, sun.os.patch.level=unknown, java.library.path=/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib, java.vendor=Oracle Corporation, java.vm.info=mixed mode, java.vm.version=11.0.2+9, sun.io.unicode.encoding=UnicodeLittle, java.class.version=55.0}

失败(prodhost):

{awt.toolkit=sun.awt.X11.XToolkit, java.specification.version=11, sun.cpu.isalist=, sun.jnu.encoding=ANSI_X3.4-1968, java.class.path=., java.vm.vendor=Oracle Corporation, sun.arch.data.model=64, java.vendor.url=http://java.oracle.com/, user.timezone=, os.name=Linux, java.vm.specification.version=11, sun.java.launcher=SUN_STANDARD, user.country=US, sun.boot.library.path=/usr/lib/jvm/java-11-openjdk-amd64/lib, sun.java.command=DateTest, jdk.debug=release, sun.cpu.endian=little, user.home=/root, user.language=en, java.specification.vendor=Oracle Corporation, java.version.date=2019-04-16, java.home=/usr/lib/jvm/java-11-openjdk-amd64, file.separator=/, java.vm.compressedOopsMode=32-bit, line.separator= , java.specification.name=Java Platform API Specification, java.vm.specification.vendor=Oracle Corporation, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, java.runtime.version=11.0.3+7-Ubuntu-1ubuntu218.04.1, user.name=root, path.separator=:, os.version=4.4.0-1079-aws, java.runtime.name=OpenJDK Runtime Environment, file.encoding=ANSI_X3.4-1968, java.vm.name=OpenJDK 64-Bit Server VM, java.vendor.url.bug=http://bugreport.java.com/bugreport/, java.io.tmpdir=/tmp, java.version=11.0.3, user.dir=/opt/ct/deploy, os.arch=amd64, java.vm.specification.name=Java Virtual Machine Specification, java.awt.printerjob=sun.print.PSPrinterJob, sun.os.patch.level=unknown, java.library.path=/usr/java/packages/lib:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib, java.vendor=Oracle Corporation, java.vm.info=mixed mode, sharing, java.vm.version=11.0.3+7-Ubuntu-1ubuntu218.04.1, sun.io.unicode.encoding=UnicodeLittle, java.class.version=55.0}

最佳答案

我一直在查看 DateTimeFormatterBuilder 的源代码,但我不确定,但在我看来,您的 NullPointerException 的一个可能原因是某些语言环境数据中的空时区缩写。这可能会导致 DateTimeFormatterBuilder.ZoneTextPrinterParser.getTree() 将 null 传递给 DateTimeFormatterBuilder.PrefixTree.add(),后者又不会期望 null。如果是这样,则不同的行为可能是由不同时区和不同区域设置的组合引起的。请注意,时区和区域设置是独立的。

编辑:提问者报告说我的建议没有解决这个特定问题。我保留它是因为我认为指定首选时区以解析时区缩写的可能性可能对其他几个人有所帮助。

我没有重现您的异常,因此无法给出确定的修复方法,但我建议您尝试:

    Set<ZoneId> preferredZones = Set.of(ZoneId.of("America/Goose_Bay"),
ZoneId.of("America/Moncton"), ZoneId.of("America/New_York"),
ZoneId.of("America/Chicago"), ZoneId.of("America/Denver"),
ZoneId.of("America/Los_Angeles"), ZoneId.of("America/Anchorage"),
ZoneId.of("Pacific/Honolulu"), ZoneId.of("America/Adak"),
ZoneId.of("Pacific/Pago_Pago"), ZoneId.of("Pacific/Guam"));
DateTimeFormatter hhmm_a_zzz_EEE_MMM_dd_yyyy = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("hmm a ")
.appendZoneText(TextStyle.SHORT, preferredZones)
.appendPattern(" EEE MMM d yyyy")
.toFormatter(Locale.US);

已选择首选区域以匹配您链接到的 17 个缩写:

AST        America/Goose_Bay, America/Moncton
EST EDT America/New_York
CST CDT America/Chicago
MST MDT America/Denver
PST PDT America/Los_Angeles
AKST AKDT America/Anchorage
HST Pacific/Honolulu
HAST HADT America/Adak
SST SDT Pacific/Pago_Pago
CHST Pacific/Guam

您可能想检查一下我的映射是否正确。

此外,正如其他人已经建议的那样,我已经为格式化程序指定了 Locale.US

关于java - DateTimeParseException : fails on one host, 适用于另一个相同的 JDK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56976974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com