英文:
Convert UTC string date to date format
问题
如何将字符串“2020-09-02T12:22:53.9”转换为Java中的日期格式2020-09-02T12:22:53.9?
String dateString = "2020-09-02T12:22:53.9";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'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));
此代码会在行 Instant instant = Instant.parse(dateString);
处抛出 java.time.format.DateTimeParseException: Text '2020-09-02T12:22:53.9' could not be parsed at index 21
异常。
英文:
How to convert string "2020-09-02T12:22:53.9" to date format 2020-09-02T12:22:53.9 in java?
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));
This code throws a java.time.format.DateTimeParseException: Text '2020-09-02T12:22:53.9' could not be parsed at index 21
form the line Instant instant = Instant.parse(dateString);
.
答案1
得分: 2
你的格式不正确。你使用了 mm
,而不是 MM
来表示月份。另外,在格式中你漏掉了字面上的 T
。请注意,你需要使用 HH
来表示24小时制的时间。
由于你的日期时间字符串没有包含时区信息,你需要首先将日期时间字符串解析为 LocalDateTime
,然后使用 LocalDateTime#atZone
将其转换为 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);
// 解析给定的日期时间字符串为 LocalDateTime
LocalDateTime ldt = LocalDateTime.parse(dateString, dtf);
// 将 LocalDateTime 转换为 ZonedDateTime
ZonedDateTime dateTimeInTz = ldt.atZone(zoneId);
// 以默认格式显示 ZonedDateTime
System.out.println(dateTimeInTz);
// 以自定义格式显示 ZonedDateTime
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));
// 将给定的日期时间字符串解析为 ZonedDateTime
ZonedDateTime dateTimeInTz = ZonedDateTime.parse(dateString, dtf);
// 以默认格式显示 ZonedDateTime
System.out.println(dateTimeInTz);
// 以自定义格式显示 ZonedDateTime
System.out.println(dateTimeInTz.format(dtf));
}
}
输出:
2020-02-09T12:22:53.900-06:00[America/Mexico_City]
2020-09-02T12:22:53.9
英文:
Your format is not correct. You have used mm
, instead of MM
, for the month. Also, you have missed the literal T
in the format. Note that you need to use HH
for 24-hours format time.
Since your date-time string does not have a time-zone information, you will have to parse the date-time string to LocalDateTime
and then use LocalDateTime#atZone
to convert it to ZonedDateTime
(if at all you need ZonedDateTime
) as shown below:
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));
}
}
Output:
2020-02-09T12:22:53.900-06:00[America/Mexico_City]
2020-09-02T12:22:53.9
Alternatively, you can use the ZoneId
with DateTimeFormatter
itself and then you can parse the given date-time string directly into ZonedDateTime
as shown below:
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));
}
}
Output:
2020-02-09T12:22:53.900-06:00[America/Mexico_City]
2020-09-02T12:22:53.9
答案2
得分: 1
// 代码部分不要翻译
I take it that your date string is in America/Mexico_City time zone and that you want output in the same time zone, so the same date and time. I further take it that internally in your program you want to represent the point in time as an `Instant`. The full circle from your date string to `Instant` and back may go:
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));
Output:
> 2020-09-02T17:22:53.900Z
> 2020-09-02T12:22:53.9
Your input and your identical output are in ISO 8601 format. `LocalDateTime` parses ISO 8601 format without time zone or offset as its default, that is, without any explicit formatter. For printing the `ZonedDateTime` back in the same format, we are using the built-in `DateTimeFormatter.ISO_LOCAL_DATE_TIME`. As you may have realized by now, being free from specifying our own format pattern string is a great relief.
## What went wrong in your code?
Arvind Kumar Avinash has already reported the errors in your format pattern string. More fundamentally, you cannot parse your string into an `Instant`, or more precisely, it takes something more to do that. The reason is that Java and the `Instant` class don’t know and cannot guess which time zone you intended. Your date string has date and time of day without any time zone. An `Instant` is a point in time, conceptually without any date or time of day. Your string could represent different points in time in different time zones, so only by specifying the time zone is it possible to determine the point in time.
What the `Instant` class *can* parse is a date and time *in UTC* denoted by a `Z`. An example of such a string is in the output from the `Instant` above, `2020-09-02T17:22:53.900Z`. Since your string is not in UTC (and therefore hasn’t got the `Z`), this observation doesn’t help us in your case.
## Link
- [Wikipedia article: ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)
英文:
No formatter needed
I take it that your date string is in America/Mexico_City time zone and that you want output in the same time zone, so the same date and time. I further take it that internally in your program you want to represent the point in time as an Instant
. The full circle from your date string to Instant
and back may go:
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));
Output:
> 2020-09-02T17:22:53.900Z
> 2020-09-02T12:22:53.9
Your input and your identical output are in ISO 8601 format. LocalDateTime
parses ISO 8601 format without time zone or offset as its default, that is, without any explicit formatter. For printing the ZonedDateTime
back in the same format, we are using the built-in DateTimeFormatter.ISO_LOCAL_DATE_TIME
. As you may have realized by now, being free from specifying our own format pattern string is a great relief.
What went wrong in your code?
Arvind Kumar Avinash has already reported the errors in your format pattern string. More fundamentally, you cannot parse your string into an Instant
, or more precisely, it takes something more to do that. The reason is that Java and the Instant
class don’t know and cannot guess which time zone you intended. Your date string has date and time of day without any time zone. An Instant
is a point in time, conceptually without any date or time of day. Your string could represent different points in time in different time zones, so only by specifying the time zone is it possible to determine the point in time.
What the Instant
class can parse is a date and time in UTC denoted by a Z
. An example of such a string is in the output from the Instant
above, 2020-09-02T17:22:53.900Z
. Since your string is not in UTC (and therefore hasn’t got the Z
), this observation doesn’t help us in your case.
Link
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论