【问题标题】:Java ParseException when trying to convert Json response into date尝试将 Json 响应转换为日期时出现 Java ParseException
【发布时间】:2018-05-17 14:59:59
【问题描述】:

目前正在尝试获取我的日期的 Json 响应,以正确的日期格式显示。 下面是我的代码,后面是我得到的错误:

String expires = js.getString("expires["+i+"]");

            SimpleDateFormat sdf = new SimpleDateFormat("dd MMMMM yyyy hha");
            Date expiration = sdf.parse(expires);
System.out.println(expiration);

错误:

java.text.ParseException: Unparseable date: "2018-08-13T06:37:31Z"

    at java.text.DateFormat.parse(DateFormat.java:366)
    at fablemedia.demo.GoDaddyGET.Test(GoDaddyGET.java:78)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

我该如何解决这个问题? 谢谢。

【问题讨论】:

  • 你试过我的答案了吗?它按预期工作并且更清洁
  • 我建议您避免使用 SimpleDateFormat 类。它不仅过时了,而且出了名的麻烦。今天我们在java.time, the modern Java date and time API 中做得更好。
  • 您的预期/期望结果是什么?
  • @OleV.V.我真正需要的只是日期和年份,时间并不是很必要,但包含它肯定不会有坏处
  • 对不起,我不清楚。我的意思是,哪个时区的时间?它制造了巨大的差异。日期也各不相同:在所有时区都不是同一天。请在寻求调试帮助时了解这一点。始终尽可能准确地包含程序所需的行为。

标签: java json date date-format


【解决方案1】:
  1. 你为什么要使用SimpleDateFormatter,它充满了糟糕的设计和低效率。

我建议你使用新的 DateTime api。

public static void main(String[] args) throws ParseException {

    String[] dateArray = new String[10]; // this can be a list as well (containing the date strings or null

    for (String dateStr : dateArray) {
        if (dateStr != null) {
            LocalDateTime parse = LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_DATE_TIME);
            String format = parse.format(DateTimeFormatter.ofPattern("dd MMM yyyy hha"));
            System.out.println(format);
        }
    }
}

【讨论】:

  • 谢谢,但是我可能忘记告诉你我在 foreach 循环中执行此操作 * 数组的大小,并且并非数组的所有元素都包含此“过期”值,这会导致以下错误:“java.lang.NullPointerException: text”,在线:“LocalDateTime parse = LocalDateTime.parse(expires, DateTimeFormatter.ISO_DATE_TIME);” .但是对于包含“过期”值的那些它可以工作,所以感谢这个。
  • 如果有效!我建议你接受这个答案。
【解决方案2】:

时区是 CEST btw

时区至关重要。要以所需时区的时间输出:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "dd MMMM yyyy hha", Locale.ENGLISH);

    String expires = "2018-08-13T06:37:31Z";
    Instant inst = Instant.parse(expires);
    System.out.println(inst.atZone(ZoneId.of("Europe/Warsaw")).format(formatter));

打印出来:

2018 年 8 月 13 日上午 8 点

我使用欧洲/华沙作为时区,请选择您喜欢的时区。许多时区在夏季呈现为 CEST,但它们并不相同。波兰和其他中欧国家在夏季比 UTC 时间早 2 小时,因此当我们解析的到期字符串为 06:37 UTC 时,时间被指定为 08AM(尾随 Z 表示祖鲁时区或偏移零或只是UTC)。

我指定了Locale.ENGLISH,因为除了英语之外几乎不使用 AM 和 PM,但同样,您应该自己选择。

要解析的字符串在某个时间点遵循 ISO 8601 格式,因此我将其解析为 Java Instant 而不指定格式化程序。 java.time 的类,现代 Java 日期和时间 API,将 ISO 8601 解析为默认值。

不要在 2018 年使用 DateSimpleDateFormat。这些课程早已过时且设计不佳。特别是SimpleDateFormat 以麻烦而闻名。 java.time 更好用。

链接

【讨论】:

    【解决方案3】:

    您应该使用以下日期格式。

    String expires = "2018-08-13T06:37:31Z";
    SimpleDateFormat source = new SimpleDateFormat("YYYY-MM-DD'T'HH:mm:ss'Z'");
    SimpleDateFormat target = new SimpleDateFormat("dd MMMMM yyyy hha");
    
    Date expiration = source.parse(expires);
    
    String finalDate = target.format(expiration);
    System.out.println(finalDate);
    

    【讨论】:

    • 尝试执行此操作时,它将日期打印为“Sun Dec 31 06:37:31 CET 2017”。这是错误的。另外,也许我应该提到这是在 foreach 循环中,并且迭代了从中获取信息的数组的大小。此外,它经历的一些值甚至没有“过期”值,这导致我在“日期过期 = sdf.parse(expires);”行出现 NullPointerException(java.lang.NullPointerException)。
    • 首先您必须将字符串转换为日期,然后将日期转换为您想要的格式。您跳过了第一步,这就是您遇到异常的原因。对过期添加空检查以避免 NPE。我更新了我的答案。
    • 源模式完全错误,请参阅符号 Y(而不是 y)、D(而不是 d)和 Z(不应转义)的用法。
    • YYYY-MM-DD'T'HH:mm:ss'Z' 是非常错误的。你需要注意那些字母的大小写。虽然T 是文字,是格式的一部分,但Z 是偏移量,应该这样解析,否则会得到不正确的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多