【发布时间】:2019-11-20 10:49:35
【问题描述】:
我完全感到困惑。我在本地和生产主机上都使用 OpenJdk 11.0.3。一个解析日期,一个不解析。关于可能导致差异的任何想法?
编辑:最后提到的 hacky workaround
相同的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=从零开始,line.separator= , java.specification.name=Java 平台 API 规范, java.vm.specification.vendor=Oracle Corporation, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, sun.management.compiler=HotSpot 64 位分层编译器, 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虚拟机规范,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公司,java.vm.info=混合模式,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 平台 API 规范, java.vm.specification.vendor=Oracle Corporation, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, sun.management.compiler=HotSpot 64 位分层编译器, 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 位服务器 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虚拟机规范、java.awt.printerjob=sun.print.PSPrinterJob、sun.os.patch。级别=未知,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=混合模式, 共享, java.vm.version=11.0.3+7-Ubuntu-1ubuntu218 .04.1, sun.io.unicode.encoding=UnicodeLittle, java.class.version=55.0}
【问题讨论】:
-
好问题,我的想法也到了那里:)。不,不同的时区(我:PDT,prod:UTC),但我认为这无关紧要,因为它在要解析的日期中有一个时区字段。
-
会不会是语言环境妨碍了?
-
告诉我们更多关于您的两个环境的信息。
-
顺便说一下,这是日期时间字符串的可怕格式。
MDT不是 real time zone。如果打算针对北美中部使用的区域,则实时区域将是America/Denver或America/Edmonton。如果可能,请告知此数据的发布者有关 ISO 8601 的信息。 -
我无法在 Java 9.0.4 上重现您的确切堆栈跟踪。但是我相信语言环境问题是一个很好的猜测。
AM、MDT、Wed和Jul都是特定于语言的,可以在英语语言环境中解析,而在其他地方通常无法解析。