首页 > 解决方案 > SimpleDateFormat 解析 2018-11-08_21h34m46sZ

问题描述

您好想将 UTC 时间转换为当地时间,我正在这样做

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

    String timeStr1 = "2018-11-08_21h34m46sZ";

    String formatStr1 = "yyyy-MM-dd_HH'h'mm'm'ss's'Z";

    SimpleDateFormat formatter = new SimpleDateFormat( formatStr1 );
    formatter.setTimeZone( TimeZone.getTimeZone( "UTC" ) );

    Date date1 = formatter.parse( timeStr1 );
    System.out.println( date1 );

    }
}

我得到一个解析异常,因为 od Z,但是当我这样做时

String formatStr1 = "yyyy-MM-dd_HH'h'mm'm'ss'sZ'";

它通过了,但这有效吗?这不是将 sZ 视为单个常数而不是将 Z 视为时区标记吗?

标签: javatimezonesimpledateformatutcdatetime-parsing

解决方案


你是正确的,它Z表示Zulu time,UTC 的另一个名称。您也可以将其视为与 UTC 的偏移量为零。因此,您需要将其解析Z为偏移量,以确保正确解释您的时间。

java.time

但是,不要使用SimpleDateFormat. 这是出了名的麻烦和过时。也不要使用Date,它也已经过时了,而且它也有设计问题。

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd_H'h'm'm's's'X");
    String timeStr1 = "2018-11-08_21h34m46sZ";
    Instant instant1 = formatter.parse(timeStr1, Instant::from);
    System.out.println(instant1);

输出:

2018-11-08T21:34:46Z

为了完整起见:

想要将……转换为当地时间

以美国/多伦多为例:

    ZonedDateTime dateTime = instant1.atZone(ZoneId.of("America/Toronto"));
    System.out.println(dateTime);

输出:

2018-11-08T16:34:46-05:00[美国/多伦多]

在您询问的评论中Z

如果我根本不包括它会有什么不同?

两件事情:

  • 如果没有,您要确保字符串包含所需的偏移量和对象,否则您可能会冒着错误传递而被忽视的风险。这称为输入验证。
  • 正如我所提到的,您希望将其解析Z为偏移量,或者您无法从解析的值中提取明确的时间点。

链接: Oracle 教程:日期时间解释如何使用java.time.


推荐阅读