DateTimeFormatter exception - java

I am having issues with the DateTimeFormatter in Java.
I have the following code:
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDateTime startDate = LocalDateTime.now();
LocalDateTime endDate = LocalDateTime.parse(ceremonyDetails.getDate(), format);
System.out.println(ChronoUnit.DAYS.between(startDate, endDate)); format);
Which should print days between now and date from string, of format 'dd/MM/yyyy', such as '29/09/2016'.
However, I am getting this error:
java.time.format.DateTimeParseException: Text '29/09/2016' could not
be parsed: Unable to obtain LocalDateTime from TemporalAccessor:
{},ISO resolved to 2016-09-29 of type java.time.format.Parsed] with
root cause java.time.DateTimeException: Unable to obtain LocalTime
from TemporalAccessor: {},ISO resolved to 2016-09-29 of type
java.time.format.Parsed
What am I missing?

You should use LocalDate rather than LocalDateTime. One is for a date-only value, the other for a date with time-of-day value.
LocalDate.parse( "29/09/2016" , DateTimeFormatter.ofPattern("dd/MM/yyyy") )
See examples on the DateTimeFormatter class documentation page.

Related

Unable to obtain ZoneOffset from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2019-12-26 of type java.time.format.Parsed

I am trying to parse a string to an OffsetDateTime but getting the following error:
Unhandled exception.
java.time.format.DateTimeParseException: Text '26122019' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2019-12-26 of type java.time.format.Parsed
Example of the string I am attempting to parse looks like 26122019 and the value in the database looks like 2018-08-31.
I got another error prior that sent me on this path when while writing a JPA query for these values #Param("filterEndDate") OffsetDateTime filterEndDate,.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime fromDate = OffsetDateTime.parse(filterFromDate,formatter);
OffsetDateTime toDate = OffsetDateTime.parse(filterEndDate,formatter);
then I adjusted my code
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("ddMMyyyy")
.parseDefaulting(ChronoField.NANO_OF_DAY, 0)
.toFormatter()
.withZone(ZoneOffset.UTC);
and got the following error:
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1577318400},ISO,Z resolved to 2019-12-26T00:00 of type java.time.format.Parsed
-----update 1----
code
LocalDate fromDate = LocalDate.parse(filterFromDate,DateTimeFormatter.ofPattern("ddMMyyyy"));
error
java.time.format.DateTimeParseException: Text '2019-12-20' could not be parsed at index 2
I am showing two ways.
Parse into LocalDate and convert
To me the simple way would go like this:
String filterFromDate = "26122019";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy");
OffsetDateTime fromDate = LocalDate.parse(filterFromDate, formatter)
.atStartOfDay(ZoneOffset.UTC)
.toOffsetDateTime();
System.out.println(fromDate);
Output from this snippet is:
2019-12-26T00:00Z
Since your string contains a date and no time of day and no offset, I am parsing into a LocalDate. Then I perform the conversion to OffsetDateTime afterwards.
Adjusting your advanced formatter to do the job
The way you tried can be made to work with just a simple adjustment:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("ddMMyyyy")
.parseDefaulting(ChronoField.NANO_OF_DAY, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
OffsetDateTime fromDate = OffsetDateTime.parse(filterFromDate, formatter);
The result is the same as before. java.time distinguishes between an offset and a time zone. In many places an offset can be used where a time zone is required, but not here. Your call to withZone() provided a default time zone, but no default offset. Instead I am using .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) to establish a default offset.

LocalDateTime.parse() with format that doesn't have hour, minute etc

I want to parse a date-time string to LocalDateTime. The input format may not contain hour, minute etc fields. For example it can be "yyyy M d". Given this pattern you can parse a string to a LocalDate, but not LocalDateTime. I want to create LocalDateTime.
There is a way to do this with DateTimeFormatterBuilder as shown below.
// this code works. But I don't want to use DateTimeFormatterBuilder
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.parseDefaulting(HOUR_OF_DAY, 12)
.parseDefaulting(MINUTE_OF_HOUR, 13)
.parseDefaulting(SECOND_OF_MINUTE, 14)
.toFormatter();
System.out.println(LocalDateTime.parse("2015-09-05", formatter));
But I want to use DateTimeFormatter.ofPattern() instead of DateTimeFormatterBuilder. But I don't know how to make the below code work:
// this code doesn't work.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");
System.out.println(LocalDateTime.parse("2015-09-05", formatter));
It throws the exception
Exception in thread "main" java.time.format.DateTimeParseException: Text '2015-09-05' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2015-09-05 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
...

Unable to obtain ZonedDateTime from TemporalAccessor:

I have a date in the following format, I need to parse it and convert to an epoch time.
2018-11-08 08:17:18.696124
I have the following code.
String dateString = "2018-11-08 08:17:18.696124";
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
ZonedDateTime dateTime = ZonedDateTime.parse(dateString, fmt);
When I run, I get the following error.
Text '2018-11-08 08:17:18.696124' could not be parsed: Unable to
obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to
2018-11-08T08:17:18.696124 of type java.time.format.Parsed
Any help on what I am doing wrong here?
A zoned date time, as the name suggests, needs a zone. Your timestamp format does not include one, so the parsing fails.
You should parse into a LocalDateTime and then apply the correct zone. For example:
String dateString = "2018-11-08 08:17:18.696124";
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
LocalDateTime dateTime = LocalDateTime.parse(dateString, fmt);
ZonedDateTime london = dateTime.atZone(ZoneId.of("Europe/London"));

ZonedDateTime parse exception

I am trying to convert string to ZonedDateTime.
I have tried following:
SimpleDateFormat zonedDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
zonedDateTimeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
long timeMs = zonedDateTimeFormat.parse("2017-07-18T20:26:28.582+03:00[Asia/Istanbul]").getTime();
It gives java.text.ParseException: Unparseable date
How can I parse the following string into ZonedDateTime
2017-07-18T20:26:28.582+03:00[Asia/Istanbul]
The java.time API has many inbuilt-formats that simplify parsing and formatting process. The String you are trying to parse is in the standard ISO_ZONED_DATE_TIME format. So, you could parse it easily in the following way and then get the milliseconds from the epoch:
DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME ;
ZonedDateTime zdt = ZonedDateTime.parse(
"2017-07-18T20:26:28.582+03:00[Asia/Istanbul]",
formatter); // prints 2017-07-18T20:26:28.582+03:00[Asia/Istanbul]
long timeInMs = zdt.toInstant().toEpochMilli();
ZonedDateTime.parse seems to be designed to handle the exact string you provided. There is no need to go through the old SimpleDateFormat
For ZonedDateTime we need to use ZonedDateTime.parse method with DateTimeFormatter. If I am not wrong you have an ISO date:
ZonedDateTime zonedDateTime = ZonedDateTime.parse(
"2017-07-18T20:26:28.582+03:00[Asia/Istanbul]",
DateTimeFormatter.ISO_DATE_TIME
);
System.out.println(zonedDateTime); //2017-07-18T20:26:28.582+03:00[Asia/Istanbul]
You can use either ISO_ZONED_DATE_TIME or ISO_DATE_TIME. Both are able to parse a date-time with offset and zone.

Java 8 DateTimeFormatter can't parse a date formatted by itself

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss z");
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
// 2016-10-10 09:28:45 PDT
String s = zonedDateTime.format(formatter);
// this call fails
ZonedDateTime.parse(s, formatter);
What's wrong with the given snippet, shouldn't formatter.parse(date.format(formatter)) evaluate to the same date ?
Exception :
java.time.DateTimeException: Unable to obtain LocalTime from
TemporalAccessor: {MilliOfSecond=0, MicroOfSecond=0, HourOfAmPm=9,
MinuteOfHour=28, NanoOfSecond=0,
SecondOfMinute=45},ISO,America/Los_Angeles resolved to 2016-10-10 of
type java.time.format.Parsed
Since you have specified hh (lower case h) for the 12 hour clock you have lost the information about whether this is AM / PM so the parse is complaining about that.
Using yyyy-MM-dd hh:mm:ss a Z to include the AM/PM indicator works.
java.time.ZonedDateTime.parse("2016-10-10T09:28:45-07:00");
java.time.LocalDate.parse("2016-10-10");

Categories

Resources