Reputation: 444
I am trying to convert a string in OffsetDateTime
but getting below error.
java.time.format.DateTimeParseException: Text '20150101' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2015-01-01 of type java.time.format.Parsed
Code : OffsetDateTime.parse("20150101", DateTimeFormatter.ofPattern("yyyyMMdd"));
Expected output: OffsetDateTime object with date 20150101.
I really appreciate any help you can provide.
Thanks,
Upvotes: 21
Views: 110084
Reputation: 79055
Z
not literalThe accepted answer has a serious problem: it uses the literal, 'Z'
in the pattern to specify the UTC offset. 'Z'
is just a character literal whereas Z
is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the UTC offset (+00:00 hours). Check 'Z'
is not the same as Z
to learn more about it.
DateTimeFormatter.ofPattern( "yyyy-MM-dd'T'HH:mm:ssZ" ) // Z is a formatting code, not a string literal.
DateTimeFormatter.BASIC_ISO_DATE
Apart from this, the parsing code can be improved by using the predefined formatter, DateTimeFormatter#BASIC_ISO_DATE
.
LocalDate.parse("20150101", DateTimeFormatter.BASIC_ISO_DATE)
Also, one should always specify a timezone explicitly; otherwise, the JVM will use the system's default timezone, a common cause of many problems developers face.
Demo:
class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("20150101", DateTimeFormatter.BASIC_ISO_DATE);
// Convert date into a ZonedDateTime at the start of the day in the
// desired timezone e.g. ZoneId.of("Etc/UTC")
ZonedDateTime zdt = date.atStartOfDay(ZoneId.of("Etc/UTC"));
// Convert the obtained ZonedDateTime into an OffsetDateTime
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
}
}
Output:
2015-01-01T00:00Z
Learn about the modern date-time API from Trail: Date Time
Upvotes: 2
Reputation: 1454
As Pallavi said correctly OffsetDateTime makes only in the context of a offset. Hence to go from a date string to an OffsetDateTime, you need a timezone!
Here is the recipe. Find yourself a Timezone, UTC or other.
ZoneId zoneId = ZoneId.of("UTC"); // Or another geographic: Europe/Paris
ZoneId defaultZone = ZoneId.systemDefault();
Make the LocalDateTime, works the same with LocalDate.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDateTime dateTime = LocalDateTime.parse("2022-01-28T14:29:10.212", formatter);
An offset makes only sense for a timezone and a time. For instance, Eastern Time hovers between GMT-4 and GMT-5 depending on the time of year.
ZoneOffset offset = zoneId.getRules().getOffset(dateTime);
Finally you can make your OffsetDateTime from both the time and the offset:
OffsetDateTime offsetDateTime = OffsetDateTime.of(dateTime, offset);
Hope this helps anyone.
Upvotes: 2
Reputation: 444
Thanks everyone for your reply. Earlier I was using joda datetime (look at below method) to handle date and datetime both but I wanted to use Java8 libraries instead of the external libraries.
static public DateTime convertStringInDateFormat(String date, String dateFormat){
DateTimeFormatter formatter = DateTimeFormat.forPattern(dateFormat);
return formatter.parseDateTime(date);
}
I was expecting same with OffsetDateTime but got to know we can use ZonedDateTime or OffsetDateTime if we want to work with a date/time in a certain time zone. As I am working on Period and Duration for which LocalDate can help.
String to DateTime:
LocalDate date =
LocalDate.parse("20150101", DateTimeFormatter.ofPattern("yyyyMMdd"));
LocalDate to desired string format:
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
date.atStartOfDay().format(DateTimeFormatter.ofPattern(dateFormat));
Upvotes: 4
Reputation: 1215
Use a LocalDate instead of offsetDatetime for your case as you want to parse only date (no time/offset). The usage of offsetDatetime is very well discussed here
Upvotes: 1
Reputation: 3901
OffsetDateTime
represents a date-time with an offset , for eg.
2007-12-03T10:15:30+01:00
The text you are trying to parse does not conform to the requirements of OffsetDateTime.
See https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html
The string being parsed neither contains the ZoneOffset nor time. From the string and the pattern of the formatter, it looks like you just need a LocalDate. So, you could use :
LocalDate.parse("20150101", DateTimeFormatter.ofPattern("yyyyMMdd"));
Upvotes: 15