DateTimeParseException:在一台主机上失败,在另一台主机上工作,同一个 JDK

我完全感到困惑。我在本地和生产主机上都在使用 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)

不同的结果:


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)

慕尼黑5688855
浏览 233回答 5
5回答

狐的传说

我一直在查看 的源代码DateTimeFormatterBuilder,但我不确定,但在我看来,您的一个可能原因NullPointerException是某些区域设置数据中的空时区缩写。这可能会导致DateTimeFormatterBuilder.ZoneTextPrinterParser.getTree()将 null 传递给DateTimeFormatterBuilder.PrefixTree.add(),而后者又不期望 null。如果是这样,则不同的行为可能是由不同时区和不同区域设置的组合引起的。请注意,时区和语言环境是独立的。编辑:提问者报告说我的建议没有解决这个特定问题。我保留它是因为我认为指定首选时区以解析时区缩写的可能性可能对其他几个人有所帮助。我没有重现您的异常,因此无法给出确定的修复方法,但我建议您尝试:&nbsp; &nbsp; Set<ZoneId> preferredZones = Set.of(ZoneId.of("America/Goose_Bay"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZoneId.of("America/Moncton"), ZoneId.of("America/New_York"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZoneId.of("America/Chicago"), ZoneId.of("America/Denver"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZoneId.of("America/Los_Angeles"), ZoneId.of("America/Anchorage"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZoneId.of("Pacific/Honolulu"), ZoneId.of("America/Adak"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZoneId.of("Pacific/Pago_Pago"), ZoneId.of("Pacific/Guam"));&nbsp; &nbsp; DateTimeFormatter hhmm_a_zzz_EEE_MMM_dd_yyyy = new DateTimeFormatterBuilder()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .parseCaseInsensitive()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .appendPattern("hmm a ")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .appendZoneText(TextStyle.SHORT, preferredZones)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .appendPattern(" EEE MMM d yyyy")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .toFormatter(Locale.US);已选择首选区域以匹配您链接到的 17 个缩写:AST&nbsp; &nbsp; &nbsp; &nbsp; America/Goose_Bay, America/MonctonEST EDT&nbsp; &nbsp; America/New_YorkCST CDT&nbsp; &nbsp; America/ChicagoMST MDT&nbsp; &nbsp; America/DenverPST PDT&nbsp; &nbsp; America/Los_AngelesAKST AKDT&nbsp; America/AnchorageHST&nbsp; &nbsp; &nbsp; &nbsp; Pacific/HonoluluHAST HADT&nbsp; America/AdakSST SDT&nbsp; &nbsp; Pacific/Pago_PagoCHST&nbsp; &nbsp; &nbsp; &nbsp;Pacific/Guam您可能想检查我的映射是否正确。此外,正如其他人已经建议的那样,我已经Locale.US为格式化程序指定了。

收到一只叮咚

的确,这很神秘。null作为尝试生成错误的一部分,这似乎很奇怪。我无法重现您的问题,我已经尝试了 2 个 Java 8 和 12 环境。我有几个建议:Locale在解析诸如日期名称或月份名称之类的文本时始终指定 a 。在单独的方法中,将代码简化到绝对最小值,以确保没有副作用。通过调用转储有关 JVM 环境的信息System.getProperties()。代码:package work.basil.example;import java.time.ZonedDateTime;import java.time.format.DateTimeFormatter;import java.time.format.DateTimeFormatterBuilder;import java.util.Locale;public class App {&nbsp; &nbsp; public static void main ( String[] args ) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println ( "Hello World!" );&nbsp; &nbsp; &nbsp; &nbsp; App app = new App ();&nbsp; &nbsp; &nbsp; &nbsp; app.doIt ();&nbsp; &nbsp; }&nbsp; &nbsp; private void doIt ( ) {&nbsp; &nbsp; &nbsp; &nbsp; DateTimeFormatterBuilder builder =&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new DateTimeFormatterBuilder ()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .parseCaseInsensitive ()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .appendPattern ( "hmm a zzz EEE MMM d yyyy" );&nbsp; &nbsp; &nbsp; &nbsp; Locale locale = Locale.US;&nbsp; &nbsp; &nbsp; &nbsp; DateTimeFormatter f = builder.toFormatter ( locale );&nbsp; &nbsp; &nbsp; &nbsp; String input = "948 AM MDT Wed Jul 10 2019";&nbsp; &nbsp; &nbsp; &nbsp; ZonedDateTime zdt = ZonedDateTime.parse ( input , f );&nbsp; &nbsp; &nbsp; &nbsp; System.out.println ( "zdt.toString() = " + zdt );&nbsp; &nbsp; &nbsp; &nbsp; System.out.println ( System.getProperties () );&nbsp; &nbsp; }}我成功地运行了这个:我自己的 Mac Mini (2018) 和 macOS Mojave 10.14.5 使用来自 AdoptOpenJDK 和 HotSpot 的 Java 12.0.1+12。IdeOne.com 从带有 HotSpot 的 Oracle JDK 运行 java.version=1.8.0_112。查看此代码实时运行。带有来自 AdoptOpenJDK.net 的 OpenJDK 11.0.3+7 的 Ubuntu 18.04.1 LTS(在 Mac 上的 Parallels 虚拟机中运行)。带有来自Oracle 站点的 Oracle JDK 11.0.3+12 的 Ubuntu 18.04.2 LTS 。所有这些结果相同。zdt.toString() = 2019-07-10T09:48-06:00[美国/丹佛]系统属性苹果{awt.toolkit=sun.lwawt.macosx.LWCToolkit,java.specification.version=12,sun.jnu.encoding=UTF-8,java.class.path=/Users/basilbourque/IdeaProjects/Demo/target/classes: /Users/basilbourque/.m2/repository/org/threeten/threeten-extra/1.5.0/threeten-extra-1.5.0.jar, java.vm.vendor=AdoptOpenJDK, sun.arch.data.model=64, java.vendor.url=&nbsp;https://adoptopenjdk.net/&nbsp;, java.vm.specification.version=12, os.name=Mac OS X, sun.java.launcher=SUN_STANDARD, user.country=US, sun.boot .library.path=/Library/Java/JavaVirtualMachines/adoptopenjdk-12.jdk/Contents/Home/lib, sun.java.command=work.basil.example.App, http.nonProxyHosts=local|&nbsp;.local|169.254/16|.169.254/16, jdk.debug=release, sun.cpu.endian=little, user.home=/Users/basilbourque, user.language=en, java.specification.vendor=Oracle Corporation, java.version.date=2019 -04-16,java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-12.jdk/Contents/Home,file.separator=/,java.vm.compressedOopsMode=零基础,line.separator=,java.vm。 specification.vendor=Oracle Corporation,java.specification.name=Java 平台 API 规范,java.awt.graphicsenv=sun.awt.CGraphicsEnvironment,sun.management.compiler=HotSpot 64 位分层编译器,ftp.nonProxyHosts=local|&nbsp;.local|169.254/16|.169.254/16, java.runtime.version=12.0.1+12, user.name=basilbourque, path.separator=:, os.version=10.14.5, java.runtime.name=OpenJDK Runtime Environment, file.encoding =UTF-8,java.vm.name=OpenJDK 64 位服务器 VM,java.vendor.version=AdoptOpenJDK,java.vendor.url.bug=&nbsp;https://github.com/AdoptOpenJDK/openjdk-build/issues,java.io.tmpdir=/var/folders/qk/grjjffnj7ml_r54rrb1c2pbw0000gn/T/,java.version=12.0.1,user.dir=/Users/basilbourque/IdeaProjects/Demo,os.arch=x86_64,java.vm。 specification.name=Java虚拟机规范,java.library.path=/Users/basilbourque/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions :/usr/lib/java:., java.vm.info=混合模式, 共享, java.vendor=AdoptOpenJDK, java.vm.version=12.0.1+12, sun.io.unicode.encoding=UnicodeBig, socksNonProxyHosts =本地|&nbsp;.local|169.254/16|&nbsp;.169.254/16,java.class.version=56.0}IdeOne.com{java.runtime.name=Java(TM) SE Runtime Environment, sun.boot.library.path=/opt/jdk/jre/lib/amd64, java.vm.version=25.112-b15, java.vm.vendor=甲骨文公司,java.vendor.url=&nbsp;http://java.oracle.com/, path.separator=:, java.vm.name=Java HotSpot(TM) 64 位服务器 VM, file.encoding.pkg=sun.io, user.country=US, sun.java.launcher=SUN_STANDARD, sun. os.patch.level=未知,java.vm.specification.name=Java 虚拟机规范,user.dir=/home/uXdFYs,java.runtime.version=1.8.0_112-b15,java.awt.graphicsenv=sun。 awt.X11GraphicsEnvironment,java.endorsed.dirs=/opt/jdk/jre/lib/endorsed,os.arch=amd64,java.io.tmpdir=/tmp,line.separator=,java.vm.specification.vendor=Oracle公司,os.name=Linux,sun.jnu.encoding=ANSI_X3.4-1968,java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr /lib,java.specification.name=Java 平台 API 规范,java.class.version=52.0,sun.management.compiler=HotSpot 64 位分层编译器,os.version=3.16.0-4-amd64,user.home =?, user.timezone=, java.awt.printerjob=sun.print。PSPrinterJob, file.encoding=UTF-8, java.specification.version=1.8, java.class.path=tested.zip, user.name=?, java.vm.specification.version=1.8, sun.java.command= tested.zip,java.home=/opt/jdk/jre,sun.arch.data.model=64,user.language=en,java.specification.vendor=Oracle Corporation,awt.toolkit=sun.awt.X11。 XToolkit,java.vm.info=混合模式,java.version=1.8.0_112,java.ext.dirs=/opt/jdk/lib,sun.boot.class.path=/opt/jdk/jre/lib/resources .jar:/opt/jdk/jre/lib/rt.jar:/opt/jdk/jre/lib/sunrsasign.jar:/opt/jdk/jre/lib/jsse.jar:/opt/jdk/jre/lib /jce.jar:/opt/jdk/jre/lib/charsets.jar:/opt/jdk/jre/lib/jfr.jar:/opt/jdk/jre/classes, java.vendor=Oracle Corporation, file.separator =/, java.vendor.url.bug=zip,java.home=/opt/jdk/jre,sun.arch.data.model=64,user.language=en,java.specification.vendor=Oracle Corporation,awt.toolkit=sun.awt.X11.XToolkit, java.vm.info=混合模式,java.version=1.8.0_112,java.ext.dirs=/opt/jdk/lib,sun.boot.class.path=/opt/jdk/jre/lib/resources.jar :/opt/jdk/jre/lib/rt.jar:/opt/jdk/jre/lib/sunrsasign.jar:/opt/jdk/jre/lib/jsse.jar:/opt/jdk/jre/lib/jce .jar:/opt/jdk/jre/lib/charsets.jar:/opt/jdk/jre/lib/jfr.jar:/opt/jdk/jre/classes, java.vendor=Oracle Corporation, file.separator=/ , java.vendor.url.bug=zip,java.home=/opt/jdk/jre,sun.arch.data.model=64,user.language=en,java.specification.vendor=Oracle Corporation,awt.toolkit=sun.awt.X11.XToolkit, java.vm.info=混合模式,java.version=1.8.0_112,java.ext.dirs=/opt/jdk/lib,sun.boot.class.path=/opt/jdk/jre/lib/resources.jar :/opt/jdk/jre/lib/rt.jar:/opt/jdk/jre/lib/sunrsasign.jar:/opt/jdk/jre/lib/jsse.jar:/opt/jdk/jre/lib/jce .jar:/opt/jdk/jre/lib/charsets.jar:/opt/jdk/jre/lib/jfr.jar:/opt/jdk/jre/classes, java.vendor=Oracle Corporation, file.separator=/ , java.vendor.url.bug=/opt/jdk/jre/lib/sunrsasign.jar:/opt/jdk/jre/lib/jsse.jar:/opt/jdk/jre/lib/jce.jar:/opt/jdk/jre/lib/charsets。 jar:/opt/jdk/jre/lib/jfr.jar:/opt/jdk/jre/classes, java.vendor=Oracle 公司, file.separator=/, java.vendor.url.bug=/opt/jdk/jre/lib/sunrsasign.jar:/opt/jdk/jre/lib/jsse.jar:/opt/jdk/jre/lib/jce.jar:/opt/jdk/jre/lib/charsets。 jar:/opt/jdk/jre/lib/jfr.jar:/opt/jdk/jre/classes, java.vendor=Oracle 公司, file.separator=/, java.vendor.url.bug=http://bugreport.sun.com/bugreport/&nbsp;, sun.io.unicode.encoding=UnicodeLittle, sun.cpu.endian=little, sun.cpu.isalist=}

一只斗牛犬

这终于是一个已知问题,在 Fedora 中解决了,但在 Redhat 中还没有解决:https://bugzilla.redhat.com/show_bug.cgi?id=1837376&nbsp;https://bugzilla.redhat.com/show_bug.cgi?id=1838229.问题是有缺陷的 /usr/share/javazi-1.8/tzdb.dat。

侃侃无极

我以前遇到过同样的问题,对我有用的是.toFormatter()改为.toFormatter(Locale.US).&nbsp;我不确定是什么导致了这个问题,它一定与机器的时区有关。看看这是否适合你。

呼唤远方

在 CentOS 上,只有发行版中打包的 jvm 11 和 14 失败。他们被确定为:openjdk version "11.0.7" 2020-04-14 LTSOpenJDK Runtime Environment 18.9 (build 11.0.7+10-LTS)OpenJDK 64-Bit Server VM 18.9 (build 11.0.7+10-LTS, mixed mode, sharing)或者:openjdk version "14.0.1" 2020-04-14OpenJDK Runtime Environment 20.3 (build 14.0.1+7)OpenJDK 64-Bit Server VM 20.3 (build 14.0.1+7, mixed mode, sharing)从 AdoptOpenJDK 下载,一切正常:openjdk version "14.0.1" 2020-04-14OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.1+7)OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.1+7, mixed mode, sharing)或者openjdk version "11.0.8" 2020-07-14OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)我的 Mac 上也有几乎所有的 JVM Since 1.8。他们都很好。测试的格式是:private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d HH:mm:ss zzz", Locale.ENGLISH);(编辑)代码接近所示示例:import java.time.*;import java.time.format.*;import java.util.Locale;public class DateTest {&nbsp; &nbsp; private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d HH:mm:ss zzz", Locale.ENGLISH);&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(dtf.parse("Jul 15 11:20:01 CEST"));&nbsp; &nbsp; }}以及 JVM 14 的堆栈:/usr/lib/jvm/jre-14/bin/java -XX:+ShowCodeDetailsInExceptionMessages -cp . DateTest 2>&1 | sort -u | less&nbsp; &nbsp; &nbsp; &nbsp; ... 1 more&nbsp; &nbsp; &nbsp; &nbsp; at DateTest.main(DateTest.java:9)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2021)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1878)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1882)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2040)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatter.parseUnresolved0(DateTimeFormatter.java:2111)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.parse(DateTimeFormatterBuilder.java:2372)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.add(DateTimeFormatterBuilder.java:4402)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.add0(DateTimeFormatterBuilder.java:4407)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$PrefixTree.prefixLength(DateTimeFormatterBuilder.java:4538)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$ZoneIdPrinterParser.parse(DateTimeFormatterBuilder.java:4260)&nbsp; &nbsp; &nbsp; &nbsp; at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.getTree(DateTimeFormatterBuilder.java:4149)Caused by: java.lang.NullPointerException: Cannot invoke "String.length()" because "k" is nullException in thread "main" java.time.format.DateTimeParseException: Text 'Jul 15 11:20:01 CEST' could not be parsed: Cannot invoke "String.length()" because "k" is null
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java