This question already has answers here:
Unable to obtain ZonedDateTime from TemporalAccessor using DateTimeFormatter and ZonedDateTime in Java 8
(5 answers)
Closed 4 years ago.
I need to format a ZonedDate time to format MM/dd/yyyy.
ZonedDateTime zonedDateTime = ZonedDateTime.now();
String date = DateTimeFormatter.ofPattern("MM/dd/yyyy").format(zonedDateTime);
ZonedDateTime zoneDate = ZonedDateTime.parse(date);
Getting error:
Exception in thread "main" java.time.format.DateTimeParseException: Text '12/05/2018' could not be parsed at index 0
Or if I convert my value to a String with the format I want and then try to parse it back a ZonedDate Time with my format once again:
DateTimeFormatter format = DateTimeFormatter.ofPattern("MM/dd/yyyy");
ZonedDateTime zonedDateTime = ZonedDateTime.now();
String date = DateTimeFormatter.ofPattern("MM/dd/yyyy").format(zonedDateTime);
ZonedDateTime zonedate = ZonedDateTime.parse(date, format);
I get error:
Exception in thread "main" java.time.format.DateTimeParseException: Text '12/05/2018' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2018-12-05 of type java.time.format.Parsed
I've seen plenty of questions on this, but I keep getting these parsing errors
There are two problems. First, there is no zone information in the date, and second, there is no time information. You can convert it to a LocalDate:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
ZonedDateTime zonedDateTime = ZonedDateTime.now();
String date = formatter.format(zonedDateTime);
LocalDate localdate = LocalDate.parse(date, formatter);
And you can convert a LocalDate to a ZonedDateTime by setting the time to the time at start of day, and the zone to the default system zone. Otherwise, you'd need to provide a time and a ZoneId of your choosing.
ZonedDateTime zdt = localdate.atStartOfDay(ZoneId.systemDefault());
Related
This question already has answers here:
Can't parse String to LocalDate (Java 8)
(2 answers)
Difference between year-of-era and week-based-year?
(7 answers)
Closed 2 years ago.
I have the following code:
String dateTimeInStr = "17-Jul-2020 12:12";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-YYYY HH:mm");
// OffsetDateTime offsetDateTime = OffsetDateTime.parse(dateTimeInStr, formatter);
LocalDateTime localDateTime = LocalDateTime.parse(dateTimeInStr, formatter);
System.out.println(localDateTime);
// System.out.println(offsetDateTime);
As you can see I try convert string 17-Jul-2020 12:12 to the LocalDateTime or OffsetDateTime. But nothing works.
Text '17-Jul-2020 12:12' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {WeekBasedYear[WeekFields[MONDAY,1]]=2020, MonthOfYear=7, DayOfMonth=17},ISO resolved to 12:12 of type java.time.format.Parsed
Does anyone know how to fix this issue? Thanks in advance.
Case-sensitive
You are using uppercase 'YYYY' which is the week year. Try with lowercase 'yyyy':
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm");
Locale
And specify a Locale for the human language and cultural norms used in translating the name of month.
DateTimeFormatter formatter =
DateTimeFormatter
.ofPattern("dd-MMM-yyyy HH:mm")
.withLocale( Locale.US );
See this code run live at IdeOne.com.
2020-07-17T12:12
I have this code which is producing a timestamp and then parsing.
DateTimeFormatter formatter =
DateTimeFormatter
.ofPattern("yyyyMMdd kk:HH:ss.SSSZ")
.withLocale(Locale.getDefault())
.withZone(ZoneId.systemDefault());
Instant now = Instant.now();
String formatted = formatter.format(now);
Instant parsed = formatter.parse(formatted, Instant::from);
When it runs, the last line produces an exception:
java.time.format.DateTimeParseException: Text '20180123 12:12:45.648-0500' could not be parsed: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed
Caused by: java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed
Caused by: java.time.temporal.UnsupportedTemporalTypeException: **Unsupported field: InstantSeconds**
I replace the formatter with DateTimeFormatter.ISO_INSTANT, it works correctly. The actual data produced are nearly identical. What is the disconnect?
ISO_INSTANT: 2018-01-23T16:51:25.516Z
My Format: 20180119 23:59:59.999-0800
I am required to use my format. What is the problem here?
The problem is that your format does not completely represent an Instant because your format does not have a representation for minutes at all. The formatter can correctly go from Instant and output the result in your format because an Instant has all of the data that your format requires, but your format does not have everything that an Instant requires.
Try changing your pattern to yyyyMMdd kk:HH:mm:ss.SSS, and you will see that your code now works. Note the addition of mm.
If you absolutely require a minuteless pattern, you should make your own TemporalQuery to extract the information you require from the TemporalAccessor
In this case, I simply set minutes to 0:
public class MyQuery implements TemporalQuery<Instant> {
#Override
public Instant queryFrom(TemporalAccessor temporal) {
LocalDate ld = LocalDate.from(temporal);
LocalTime lt = LocalTime.of(temporal.get(ChronoField.HOUR_OF_DAY), 0, temporal.get(ChronoField.SECOND_OF_MINUTE), temporal.get(ChronoField.NANO_OF_SECOND));
return ZonedDateTime.of(ld, lt, ZoneId.systemDefault()).toInstant();
}
}
We can then use this TemporalQuery like this:
public class Test {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyyMMdd kk:HH:mm:ss.SSS")
.withLocale(Locale.getDefault())
.withZone(ZoneId.systemDefault());
Instant now = Instant.now();
String formatted = formatter.format(now);
System.out.println(formatted);
Instant ld = formatter.parse(formatted, new MyQuery());
}
}
I know that this is an old question but if you're looking for a short answer just add a locale and zone to the DateTimeFormatter, you may also use the default ones: .withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault())
Here is an example of code:
Instant now = Instant.now();
System.out.println(now.toString());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
System.out.println(formatter.format(now));
This code will use the current instant, output the sample, format it with the date time formatter and output the formatted instant.
This question already has answers here:
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Closed 3 years ago.
Hi I am not able to understand what time format we need to use in order to parse this date2020-02-11T17:26:31-05:00 I have tried using Date formatter and simple date format but its not working
Date is coming in this form ->2020-02-11T17:26:31-05:00 I am not able to identify the type of this date
Below is snippet of code i have tried but its throwing exception
DateTimeFormatter responseFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss-SSSXXX'Z'",
Locale.ENGLISH);
responseDateTime = LocalDateTime.parse(otmmResponseDate, responseFormatter);
Notice that your date string has an offset -05:00 in it. Thus, your string does not represent a LocalDateTime, but an OffsetDateTime, and should be parsed by OffsetDateTime.parse (not everything is a LocalDateTime!):
// the format is ISO 8601, so it can be parsed directly without a DateTimeFormatter
OffsetDateTime odt = OffsetDateTime.parse("2020-02-11T17:26:31-05:00");
If you only want the local date time part of it, then you can call toLocalDateTime afterwards:
LocalDateTime ldt = odt.toLocalDateTime();
This is a datetime String that contains an offset of minus five hours. You don't even have to use a DateTimeFormatter directly, because parsing this to an OffsetDateTime will do:
public static void main(String[] args) {
String dateString = "2020-02-11T17:26:31-05:00";
OffsetDateTime odt = OffsetDateTime.parse(dateString);
System.out.println(odt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
Output:
2020-02-11T17:26:31
Not that this uses a DateTimeFormatter without an offset for the output.
Quick (I suppose) question. How to parse string like that "2018-07-22 +3:00" to OffsetDateTime (setting time to 0:0:0.0)?
DateTimeFormatter formatter =cDateTimeFormatter.ofPattern("yyyy-MM-dd xxx");
OffsetDateTime dt = OffsetDateTime.parse("2007-07-21 +00:00", formatter);
java.time.format.DateTimeParseException: Text '2007-07-21 +00:00'
could not be parsed: Unable to obtain OffsetDateTime from
TemporalAccessor: {OffsetSeconds=0},ISO resolved to 2007-07-21 of type
java.time.format.Parsed
The trick here is to start by getting the TemporalAccessor:
TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyy-MM-dd XXX").parse("2018-07-22 +03:00");
From there, you can extract a LocalDate and a ZoneOffset:
LocalDate date = LocalDate.from(ta);
ZoneOffset tz = ZoneOffset.from(ta);
And combine them like so:
ZonedDateTime zdt = date.atStartOfDay(tz);
An OffsetDateTime requires a time-of-day, but your format string doesn't supply that, so you need to tell the DateTimeFormatter to default time-of-day to midnight.
Also, offset +3:00 is invalid, since hour must be 2-digit, which means you need to fix that first.
This will do both:
public static OffsetDateTime parse(String text) {
// Fix 1-digit offset hour
String s = text.replaceFirst("( [+-])(\\d:\\d\\d)$", "$10$2");
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-dd xxx")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter();
return OffsetDateTime.parse(s, formatter);
}
Test
System.out.println(parse("2018-07-22 +3:00"));
System.out.println(parse("2018-07-22 +03:00"));
System.out.println(parse("2007-07-21 +00:00"));
Output
2018-07-22T00:00+03:00
2018-07-22T00:00+03:00
2007-07-21T00:00Z
I have this code which is producing a timestamp and then parsing.
DateTimeFormatter formatter =
DateTimeFormatter
.ofPattern("yyyyMMdd kk:HH:ss.SSSZ")
.withLocale(Locale.getDefault())
.withZone(ZoneId.systemDefault());
Instant now = Instant.now();
String formatted = formatter.format(now);
Instant parsed = formatter.parse(formatted, Instant::from);
When it runs, the last line produces an exception:
java.time.format.DateTimeParseException: Text '20180123 12:12:45.648-0500' could not be parsed: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed
Caused by: java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed
Caused by: java.time.temporal.UnsupportedTemporalTypeException: **Unsupported field: InstantSeconds**
I replace the formatter with DateTimeFormatter.ISO_INSTANT, it works correctly. The actual data produced are nearly identical. What is the disconnect?
ISO_INSTANT: 2018-01-23T16:51:25.516Z
My Format: 20180119 23:59:59.999-0800
I am required to use my format. What is the problem here?
The problem is that your format does not completely represent an Instant because your format does not have a representation for minutes at all. The formatter can correctly go from Instant and output the result in your format because an Instant has all of the data that your format requires, but your format does not have everything that an Instant requires.
Try changing your pattern to yyyyMMdd kk:HH:mm:ss.SSS, and you will see that your code now works. Note the addition of mm.
If you absolutely require a minuteless pattern, you should make your own TemporalQuery to extract the information you require from the TemporalAccessor
In this case, I simply set minutes to 0:
public class MyQuery implements TemporalQuery<Instant> {
#Override
public Instant queryFrom(TemporalAccessor temporal) {
LocalDate ld = LocalDate.from(temporal);
LocalTime lt = LocalTime.of(temporal.get(ChronoField.HOUR_OF_DAY), 0, temporal.get(ChronoField.SECOND_OF_MINUTE), temporal.get(ChronoField.NANO_OF_SECOND));
return ZonedDateTime.of(ld, lt, ZoneId.systemDefault()).toInstant();
}
}
We can then use this TemporalQuery like this:
public class Test {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyyMMdd kk:HH:mm:ss.SSS")
.withLocale(Locale.getDefault())
.withZone(ZoneId.systemDefault());
Instant now = Instant.now();
String formatted = formatter.format(now);
System.out.println(formatted);
Instant ld = formatter.parse(formatted, new MyQuery());
}
}
I know that this is an old question but if you're looking for a short answer just add a locale and zone to the DateTimeFormatter, you may also use the default ones: .withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault())
Here is an example of code:
Instant now = Instant.now();
System.out.println(now.toString());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
System.out.println(formatter.format(now));
This code will use the current instant, output the sample, format it with the date time formatter and output the formatted instant.