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);
Related
This question might sound similar to most of the other questions asked here on Stackoverflow but I could not figure out my problem.
I want to parse the string value into a date.
String dateTime = "23 Oct 2020 02:44:58 +1000"
The solution to this problem is:
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseCaseInsensitive();
builder.appendPattern("d MMM yyyy HH:mm[:ss] Z");
DateTimeFormatter dtf = builder.toFormatter();
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTime, dtf);
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);
If I want to parse the date with timezone instead like String dateTime = "23 Oct 2020 02:44:58 AEST" then I need to change the builder.appendPattern("d MMM yyyy HH:mm[:ss] Z"); from capital Z to small z as mentioned here.
The question here is how would I make my parser flexible enough for it to handle either timezone or offset value?
Note. I have used [ss] as the seconds' field is optional. And as per documentation using VV was similar to z while 'V' did not work for me.
You can add them as optional parts to the formatter, just like you did with the seconds part:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d MMM yyyy HH:mm[:ss] [Z][z]")
.toFormatter(Locale.ROOT);
Online demo
[ and ] denote an optional part: the corresponding text is consumed if it can be successfully parsed by means of the pattern within the brackets, otherwise, no text is consumed and the pattern within is skipped.
You can try using try-catch block
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseCaseInsensitive();
builder.appendPattern("d MMM yyyy HH:mm[:ss] Z");
DateTimeFormatter dtf = builder.toFormatter();
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseCaseInsensitive();
builder.appendPattern("d MMM yyyy HH:mm[:ss] z");
DateTimeFormatter dtf = builder.toFormatter();
ZonedDateTime zonedDateTime;
try {
zonedDateTime = ZonedDateTime.parse(dateTime, dtf1);
} catch (DateTimeParseException e) {
zonedDateTime = ZonedDateTime.parse(dateTime, dtf2);
}
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);
I am trying to convert a string to date format with Java8 using DateTimeFormatter in spring boot, But I receive an error [[java.time.format.DateTimeParseException: Text '10-03-2021' could not be parsed at index 0]]. I am using LocalDate because I want my output to have only date without time. What Am I doing wrong in my code.
String date= "10-03-2021"
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, MMM d, yyyy",Locale.forLanguageTag("sw-TZ"));
LocalDateTime dateTime = LocalDateTime.parse(date, formatter);
System.out.println(dateTime.format(formatter));
You need to parse date in dd-MM-yyyy pattern first and then format it to the pattern of your choice.
String date= "10-03-2021";
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate localDate = LocalDate.parse(date, format);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, MMM d, yyyy",Locale.forLanguageTag("sw-TZ"));
System.out.println(localDate.format(formatter));
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"));
I have a datetime-string WITHOUT a specified timezone.
But I want to parse it with ZonedDateTime to give it a timezone-meaning in the act of parsing.
This code is working but uses LocalDateTime for parsing - and then convert it to ZonedDateTime with giving it a timezone-meaning.
DateTimeFormatter dtf = DateTimeFormatter.ofPattern ("yyyyMMddHHmm");
String tmstr = "201810110907";
LocalDateTime tmp = LocalDateTime.parse (tnstr,dtf);
ZonedDateTime mytime = ZonedDateTime.of (tmp, ZoneId.of ("UTC"));
Is there a way I can parse it directly with ZonedDateTime?
I have tried this, but it was not working.
mytime = mytime.withZoneSameInstant(ZoneId.of("UTC")).parse(str,dtf);
You may specify a default time zone on the formatter:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmm")
.withZone(ZoneId.of("UTC"));
String tmstr = "201810110907";
ZonedDateTime mytime = ZonedDateTime.parse(tmstr, dtf);
System.out.println(mytime);
Output:
2018-10-11T09:07Z[UTC]
Bonus tip: Rather than ZoneId.of("UTC") it’s usually nicer to use ZoneOffset.UTC. If you accept the output being printed as 2018-10-11T09:07Z instead (Z meaning UTC).
java.time.format.DateTimeParseException: Text '2018-03-29 16:15:30'
could not be parsed at index 10
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
OffsetDateTime date =
OffsetDateTime.parse(entry.getValue(), fmt);
predicates.add(cb.equal(root.get(entry.getKey()), date));
You created a DateTimeFormatter with the pattern "yyyy-MM-dd" (year-month-day), but your input also contains "hours:minutes:seconds" (2018-03-29 16:15:30).
But even if you use the correct pattern, this will still throw an exception:
// now the pattern matches the input
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
OffsetDateTime date = OffsetDateTime.parse("2018-03-29 16:15:30", fmt); // DateTimeParseException
That's because an OffsetDateTime also needs the UTC offset, and the input doesn't have it. You have some alternatives:
parse it to a LocalDateTime:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date = LocalDateTime.parse("2018-03-29 16:15:30", fmt);
if you really need OffsetDateTime, you'll have to arbitrarialy choose some offset for it. Example:
LocalDateTime date = // parse the LocalDateTime as above
// use offset +02:00
OffsetDateTime odt = date.atOffset(ZoneOffset.ofHours(2));
Or you can set a default value in the formatter:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time pattern
.appendPattern("yyyy-MM-dd HH:mm:ss")
// use some offset as default (0 is UTC)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
OffsetDateTime odt = OffsetDateTime.parse("2018-03-29 16:15:30", fmt);