将UTC字符串日期转换为日期格式

问题描述

如何在Java中将字符串“ 2020-09-02T12:22:53.9”转换为日期格式2020-09-02T12:22:53.9?

String dateString = "2020-09-02T12:22:53.9";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-DD-mm hh:mm:ss.S");
ZoneId zoneId = ZoneId.of(tz);
Instant instant = Instant.parse(dateString);
zoneddatetime dateTimeInTz =zoneddatetime.ofInstant(instant,zoneId);
System.out.println(dateTimeInTz.format(dtf));

代码java.time.format.DateTimeParseException: Text '2020-09-02T12:22:53.9' Could not be parsed at index 21行中抛出Instant instant = Instant.parse(dateString);

解决方法

您的格式不正确。您已使用mm代替了MM。另外,您还错过了格式中的文字T。请注意,您需要使用HH进行24小时格式化。

由于您的日期时间字符串没有时区信息,因此您必须将日期时间字符串解析为LocalDateTime,然后使用LocalDateTime#atZone将其转换为{{1} }(如果您完全需要ZonedDateTime),如下所示:

ZonedDateTime

输出:

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

public class Main {
    public static void main(String[] args) {
        String dateString = "2020-09-02T12:22:53.9";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:ss.S");

        String tz = "America/Mexico_City";
        ZoneId zoneId = ZoneId.of(tz);

        // Parse the given date-time string to LocalDateTime
        LocalDateTime ldt = LocalDateTime.parse(dateString,dtf);

        // Convert the LocalDateTime to ZonedDateTime
        ZonedDateTime dateTimeInTz = ldt.atZone(zoneId);

        // Display ZonedDateTime in its default format
        System.out.println(dateTimeInTz);

        // Display ZonedDateTime in your custom format
        System.out.println(dateTimeInTz.format(dtf));
    }
}

或者,您可以将2020-02-09T12:22:53.900-06:00[America/Mexico_City] 2020-09-02T12:22:53.9 ZoneId一起使用,然后可以将给定的日期时间字符串直接解析为DateTimeFormatter,如下所示:

ZonedDateTime

输出:

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

public class Main {
    public static void main(String[] args) {
        String dateString = "2020-09-02T12:22:53.9";

        String tz = "America/Mexico_City";
        ZoneId zoneId = ZoneId.of(tz);

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:ss.S").withZone(ZoneId.of(tz));

        // Parse the given date-time string into ZonedDateTime
        ZonedDateTime dateTimeInTz = ZonedDateTime.parse(dateString,dtf);

        // Display ZonedDateTime in its default format
        System.out.println(dateTimeInTz);

        // Display ZonedDateTime in your custom format
        System.out.println(dateTimeInTz.format(dtf));
    }
}
,

不需要格式化程序

我认为您的日期字符串在America / Mexico_City时区中,并且您希望在相同的时区中输出,因此在相同的日期和时间。我进一步认为,在您的程序内部,您希望将时间点表示为Instant。日期字符串到Instant再返回的整个圆圈可能会出现:

    String tz = "America/Mexico_City";
    ZoneId zoneId = ZoneId.of(tz);
    
    String dateString = "2020-09-02T12:22:53.9";
    
    Instant instant = LocalDateTime.parse(dateString).atZone(zoneId).toInstant();
    System.out.println(instant);
    
    ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant,zoneId);
    System.out.println(dateTimeInTz.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

输出:

2020-09-02T17:22:53.900Z
2020-09-02T12:22:53.9

您的输入和相同的输出为ISO 8601格式。 LocalDateTime解析没有时区或偏移量作为默认值的ISO 8601格式,即没有任何显式格式化程序。为了以相同格式打印ZonedDateTime,我们使用了内置DateTimeFormatter.ISO_LOCAL_DATE_TIME。正如您可能已经意识到的那样,无需指定我们自己的格式模式字符串是一种极大的缓解。

您的代码出了什么问题?

Arvind Kumar Avinash已经报告了格式模式字符串中的错误。从根本上讲,您无法将字符串解析为Instant,或更准确地说,这需要花费更多时间。原因是Java和Instant类不知道并且无法猜测您想要的时区。您的日期字符串包含日期和时间,没有任何时区。 Instant是一个时间点,概念上没有任何日期或时间。您的字符串可能表示不同时区中的不同时间点,因此只有指定时区才能确定时间点。

Instant 可以解析的是用Z表示的日期和时间,以UTC 表示。上面Instant的输出2020-09-02T17:22:53.900Z中就是这样一个字符串的示例。由于您的字符串不在UTC中(因此未获得Z),因此这种观察对您的情况没有帮助。

链接