问题描述
如何在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
),因此这种观察对您的情况没有帮助。