Unable to obtain ZonedDateTime from TemporalAccessor: - java

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"));

Related

How to convert UTC DateTime to another Time Zone using Java 8 library?

final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
Instant.ofEpochMilli(rawDateTime.getTime()), zoneId);
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]
final ZonedDateTime zonedDateTime1 =
ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId);
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]
But I want to get the converted date time as 2031-04-26 00:00:00+5:30 as my timestamp value is in the UTC Timezone.
Please help.
First, you should not use Timestamp. You can use DateTimeFormatter to parse into a LocalDateTime.
You then zone that LocalDateTime to UTC before converting to the Calcutta zone with ZonedDateTime.withZoneSameInstant.
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
LocalDateTime localDateTime = LocalDateTime.parse("2031-04-25 18:30:00", formatter);
ZoneId calcuttaZone = ZoneId.of("Asia/Calcutta");
ZonedDateTime calcuttaZonedDateTime = localDateTime.atZone(ZoneOffset.UTC)
.withZoneSameInstant(calcuttaZone);
Using DateTimeFormatter to format ZonedDateTime:
final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
Instant.ofEpochMilli(rawDateTime.getTime()), zoneId);
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]");
System.out.println(formatter.format(zonedDateTime));
final ZonedDateTime zonedDateTime1 =
ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId);
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]
System.out.println(formatter.format(zonedDateTime1));
The output:
2031-04-25 23:00:00+05:30
2031-04-25 18:30:00+05:30
Edited: according to the comment from #Ole V.V. - The local date time has to be converted to the zonedatetime , before applying the format :
final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
LocalDateTime ldt = rawDateTime.toLocalDateTime();
final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
ZonedDateTime zdt = ldt.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(zoneId);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]");
System.out.println(formatter.format(zdt));
This will give the output:
2031-04-26 00:00:00+5:30
Instead of ZonedDateTime with named zones having (supra-)national standards like day-time-savings, use OffsetDateTime.
OffsetDateTime utc = OffsetDateTime.parse("2031-04-25T18:30:00Z");
OffsetDateTime asia = utc.withOffsetSameInstant(ZoneOffset.ofHoursMinutes(5, 30));
The default parsing is for the ISO format.
Z means zero, UTC, +0:00.
The resulting default formatting is 2031-04-26T00:00+05:30.
After comment of Ole V.V.
The above is especially error prone if summer time is involved, like in Central European Time with varying offsets +1:00 and +2:00.
Instant raw = Instant.parse("2031-04-25T18:30:00Z");
ZonedDateTime zoned = raw.atZone(ZoneId.of("Asia/Calcutta"));
OffsetDateTime offset = OffsetDateTime.from(zoned);

Convert String into java.time.ZonedDateTime

I want to convert elements of an array list into ZonedDateTime object after parsing them. A string is shown below.
"2017-02-12 06:59:00 +1300"
At the moment I use the DateTimeFormatter:
DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss ZZ");
And try to use parse, to get the time:
this.actionTime = dateTimeFormatter.parse(actionTime, ZonedDateTime::from);
See below method:
public DateCalculatorTest(String actionTime, int expectedDayOfWeek) {
DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss ZZ");
DateTimeFormatter localTimeFormatter =
DateTimeFormatter.ofPattern("YYYY-MM-dd");
this.actionTime = dateTimeFormatter.parse(actionTime, ZonedDateTime::from);
this.expectedDayOfWeek = expectedDayOfWeek;
}
However, I am not able to parse the string. I get the following error:
Text '2017-02-12 06:59:00 +1300' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {WeekBasedYear[WeekFields[SUNDAY,1]]=2017, DayOfMonth=12, MonthOfYear=2, OffsetSeconds=46800},ISO resolved to 06:59 of type java.time.format.Parsed
Is there a way to do this with java.time?
In the DateTimeFormatter years should be small letters. Replace
YYYY-MM-dd HH:mm:ss ZZ
with
yyyy-MM-dd HH:mm:ss ZZ
And you don't require two ZZ, single is enough. In your code the ZoneId instance will give you default ZoneId. It will fall back to LocalDateTime. If you want to specify the ZoneId use the following
this.actionTime = ZonedDateTime.parse(actionTime, dateTimeFormatter.withZone(ZoneId.of(<<yourxoneid>>)));
I managed to fix this using the following:
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss ZZ");
DateTimeFormatter localTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
this.symbol = symbol;
this.actionTime = ZonedDateTime.parse(actionTime, dateTimeFormatter);
this.actionDate = LocalDate.parse(expectedResult, localTimeFormatter);

DateTimeFormatter exception

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.

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");

Java 8 Convert given time and time zone to UTC time

I have a time with string type like: "2015-01-05 17:00" and ZoneId is "Australia/Sydney".
How can I convert this time information to the corresponding to UTC time using Java 8 datetime API?
Also need to considering DST stuff.
You are looking for ZonedDateTime class in Java8 - a complete date-time with time-zone and resolved offset from UTC/Greenwich. In terms of design, this class should be viewed primarily as the combination of a LocalDateTime and a ZoneId. The ZoneOffset is a vital, but secondary, piece of information, used to ensure that the class represents an instant, especially during a daylight savings overlap.
For example:
ZoneId australia = ZoneId.of("Australia/Sydney");
String str = "2015-01-05 17:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime localtDateAndTime = LocalDateTime.parse(str, formatter);
ZonedDateTime dateAndTimeInSydney = ZonedDateTime.of(localtDateAndTime, australia );
System.out.println("Current date and time in a particular timezone : " + dateAndTimeInSydney);
ZonedDateTime utcDate = dateAndTimeInSydney.withZoneSameInstant(ZoneOffset.UTC);
System.out.println("Current date and time in UTC : " + utcDate);
An alternative to the existing answer is to setup the formatter with the appropriate time zone:
String input = "2015-01-05 17:00";
ZoneId zone = ZoneId.of("Australia/Sydney");
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(zone);
ZonedDateTime utc = ZonedDateTime.parse(input, fmt).withZoneSameInstant(UTC);
Since you want to interact with a database, you may need a java.sql.Timestamp, in which case you don't need to explicitly convert to a UTC time but can use an Instant instead:
ZonedDateTime zdt = ZonedDateTime.parse(input, fmt);
Timestamp sqlTs = Timestamp.from(zdt.toInstant());
**// Refactored Logic**
ZoneId australia = ZoneId.of("Australia/Sydney");
ZoneId utcZoneID= ZoneId.of("Etc/UTC");
String ausTime = "2015-01-05 17:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
//converting in datetime of java8
LocalDateTime ausDateAndTime = LocalDateTime.parse(ausTime, formatter);
// DateTime With Zone
ZonedDateTime utcDateAndTime = ausDateAndTime.atZone(utcZoneID);
// output - 2015-01-05T17:00Z[Etc/UTC]
// With Formating DateTime
String utcDateTime = utcDateAndTime.format(formatter);
// output - 2015-01-05 17:00

Categories

Resources