【问题标题】:Parsing a Date and Time string into a ZonedDateTime object将日期和时间字符串解析为 ZonedDateTime 对象
【发布时间】:2019-03-09 00:49:02
【问题描述】:

我正在尝试解析具有已知时区中日期和时间的字符串。 字符串格式如下:

2019-03-07 00:05:00-05:00

我试过这个:

package com.example.test;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Test {

    public static void main( String[] args ) {

        ZoneId myTimeZone = ZoneId.of("US/Eastern");

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ssXX");

        ZonedDateTime zdt = ZonedDateTime.parse("2019-03-07 00:05:00-05:00", dateTimeFormatter.withZone(myTimeZone));

        System.out.println(zdt);

    }

}

这是抛出的异常:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2019-03-07 00:05:00-05:00' could not be parsed at index 19
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
    at com.example.test.Test.main(Test.java:24)
C:\Users\user\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

我使用的是 Java 1.8.0_191。

【问题讨论】:

    标签: java java-8 zoneddatetime java-time


    【解决方案1】:

    使用此模式:yyyy-MM-dd HH:mm:ssXXX

    来自docs

    偏移 X 和 x: ... 两个字母输出小时和分钟,没有 冒号,例如“+0130”。三个字母输出小时和分钟, 带有冒号,例如“+01:30”。

    因此,如果您的字符串在时区中包含冒号,则应使用 3 个“X-es”。

    大写的 Y 表示“基于周的年份”,而不是常规的 (y)。

    【讨论】:

      【解决方案2】:

      tl;博士

      OffsetDateTime.parse( 
          "2019-03-07 00:05:00-05:00".replace( " " , "T" ) 
      )
      

      使用偏移量,Luke

      您不需要时区。您的字符串与 UTC 相比具有 5 小时的 UTC 偏移量。这告诉我们一个特定的时刻,时间线上的一个点。

      ISO 8601

      将输入中间的空格替换为T 以符合 ISO 8601。java.time 类默认使用标准格式。所以不需要指定格式模式。

      OffsetDateTime

      解析为OffsetDateTime

      String input = "2019-03-07 00:05:00-05:00".replace( " " , "T" ) ;
      OffsetDateTime odt = OffsetDateTime.parse( input ) ;
      

      ZonedDateTime

      如果您确定该值适用于特定时区,则可以应用ZoneId 来获取ZonedDateTime

      注意US/Easterndeprecated as a time zone name。现代方法是Continent/Region。也许你的意思是America/New_York

      ZoneId z = ZoneId.of( "America/New_York" ) ;
      ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
      

      【讨论】:

      • 感谢您的回答 Basil,第二个选项非常有用,我选择了第一个选项,因为它确定了如何修复格式。我也不知道美国/东部已被弃用,很高兴知道。
      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多