Reputation: 107
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);
.
Upvotes: 0
Views: 1427
Reputation: 86379
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.
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.
Upvotes: 1
Reputation: 79550
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
Upvotes: 2