Convert String to LocalDateTime Java 8 - java

I'm trying to convert the following String into a LocalDateTime:
String dateStr = "2020-08-17T10:11:16.908732";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnn");
LocalDateTime dateTime = LocalDateTime.parse(dateStr, format);
But I'm hitting the following error:
java.time.format.DateTimeParseException: Text '2020-08-17T10:11:16.908732' could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
Can anyone please help to advise how I should be correctly formatting the string into a LocalDateTime?
Many thanks

You don't need to specify a DateTimeFormatter in this case because the default one will be used if you don't pass one at all:
public static void main(String[] args) {
String dateStr = "2020-08-17T10:11:16.908732";
// the following uses the DateTimeFormatter.ISO_LOCAL_DATE_TIME implicitly
LocalDateTime dateTime = LocalDateTime.parse(dateStr);
System.out.println(dateTime);
}
That code will output 2020-08-17T10:11:16.908732.
If you are insisting on using a custom DateTimeFormatter, consider the T by single-quoting it in the pattern and don't use nanosecond parsing (n) for parsing fractions of second (S), the result might be wrong otherwise.
Do it like this:
public static void main(String[] args) {
String dateStr = "2020-08-17T10:11:16.908732";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
LocalDateTime dateTime = LocalDateTime.parse(dateStr, format);
System.out.println(dateTime);
}
with the same output as above.
Note:
The result of using the pattern "yyyy-MM-dd'T'HH:mm:ss.nnnnnn" would not be equal to the parsed String, instead, it would be
2020-08-17T10:11:16.000908732

For your given DateTime string pattern should be updated "yyyy-MM-dd'T'HH:mm:ss.nnnnnn".
So the code should be like :
String dateStr = "2020-08-17T10:11:16.908732";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn");
LocalDateTime dateTime = LocalDateTime.parse(dateStr, format);
For more details around it you can refer JavaDoc.
Along that in your given input DateTime it's using 6 digits, so it can't be nano seconds. Because nano is 1/1000000000. So it will have at least 9 digits. So the correct format rather should be second fraction with 6 digits as "yyyy-MM-dd'T'HH:mm:ss.SSSSSS".
End Results comparison:
With Pattern : "yyyy-MM-dd'T'HH:mm:ss.nnnnnn"
System.out.println(LocalDateTime.parse("2020-08-17T10:11:16.908732", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn")));
Output : 2020-08-7T10:11:16.000908732
With Pattern : "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"
System.out.println(LocalDateTime.parse("2020-08-17T10:11:16.908732", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")));
Output : 2020-08-7T10:11:16.908732

Related

Java convert DateTime from "yyyy-MM-dd HH:mm:ss.SSSSSSS" to "yyyy-MM-dd HH:mm:ss.S" or from "yyyy-MM-dd HH:mm:ss.SSSSSSS" to "yyyy-MM-dd HH:mm:ss.SSS"

Java 11
I want to convert the date in "yyyy-MM-dd HH:mm:ss.SSSSSSS" to either "yyyy-MM-dd HH:mm:ss.S" or "yyyy-MM-dd HH:mm:ss.SSS" based on milliseconds value. If milliseconds are all zeros, then I just want single zero but if it is non-zero value then I want just value omitting trailing zeros.
Example :
Input : 2021-03-10 16:37:02.4230000 =>
Desired Output : 2021-03-10 16:37:02.423
Input : 2021-03-10 16:39:51.0000000 => Desired output : 2021-03-10 16:39:51.0
Input : 2021-04-22 23:03:52.0234000 => Desired output : 2021-04-22 23:03:52.0234
So, I started out with something like...
String text = "2021-03-10 16:37:02.4230000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS");
LocalDateTime ldt1 = LocalDateTime.parse("2021-03-10 16:37:02.4230000", formatter);
DateTimeFormatter shortFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
System.out.println(shortFormatter.format(ldt1));
LocalDateTime ldt2 = LocalDateTime.parse("2021-03-10 16:39:51.0000000", formatter);
System.out.println(shortFormatter.format(ldt2));
Which prints out ...
2021-03-10 16:37:02.4
2021-03-10 16:39:51.0
Hmmm 🤔, not quite what we're looking for.
Lucky for us, there's the DateTimeFormatterBuilder class. So next, I tried something like...
DateTimeFormatter toFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.appendFraction(ChronoField.MILLI_OF_SECOND, 1, 9, true)
.toFormatter();
System.out.println(toFormatter.format(ldt1));
System.out.println(toFormatter.format(ldt2));
Which prints out ...
2021-03-10 16:37:02.423
2021-03-10 16:39:51.0
Success 🎉
Now, please note, I've not really used DateTimeFormatterBuilder before, so there might be some other, really super awesome cool way to achieve the same or better result, but hay, it's a nice start
This can done using replaceAll method of String as well. you can remove the trailing zero's in the date string if there is no milisecond left after removing all trailing zero's, then append .0
private static String getMiliSecond(String input) {
// removing trailing zeros
String miliSecondTrimmed = input.replaceAll("[0.]*$", "");
// if there is there is no mili second left after removing zeros, append .0
return (!miliSecondTrimmed.contains("."))?(miliSecondTrimmed+(".0").toString()):miliSecondTrimmed;
}
This code called from main method
public static void main(String[] args) {
String input1 ="2021-03-10 16:39:51.0000000";
String input2 = "2021-03-10 16:37:02.4230000";
String miliSecond1 = getMiliSecond(input1);
String miliSecond2 = getMiliSecond(input2);
System.out.println("input1 mili:"+miliSecond1);
System.out.println("input2 mili:"+miliSecond2);
}
Output:
input1 mili:2021-03-10 16:39:51.0
input2 mili:2021-03-10 16:37:02.423

error java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24

I´m trying to pase the next String using LocalDateTime, but I always get de unparsed text found error:
java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24
Need: from 2020-10-16T18:04:59+0300 to 2020-10-16 18:04.
My code:
public String getFormattingData(String sourceData) {
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ''e", Locale.ENGLISH);
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyy HH:mm", Locale.ENGLISH);
LocalDate date = LocalDate.parse("2020-10-16T18:04:59+0300", sourceFormatter);
return newFormatter.format(date);
}
What am I doing wrong?
See the related question: Format a date using the new date time API
The source format you are looking for is: "yyyy-MM-dd'T'HH:mm:ssZ" (as mentioned by #Sweeper in his comment)
If you want the HH:mm in the output format, you need to use a LocalDateTime rather than a LocalDate
The code below works for me:
public String getFormattingData(String sourceData) {
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse("2020-10-16T18:04:59+0300", sourceFormatter);
return newFormatter.format(date);
result:
16-10-2020 18:04
You just need to correct the date pattern of source date like this:
public static String formatDate(String strDate, String srcPattern, String tgtPattern) {
DateTimeFormatter srcFormatter = DateTimeFormatter.ofPattern(srcPattern, Locale.ENGLISH);
DateTimeFormatter tgtFormatter = DateTimeFormatter.ofPattern(tgtPattern, Locale.ENGLISH);
return tgtFormatter.format(LocalDateTime.parse(strDate, srcFormatter));
}
You can also use SimpleDateFormat:
public static String formatDate(String strDate, String srcPattern,
String tgtPattern) throws ParseException {
SimpleDateFormat srcFormatter = new SimpleDateFormat(srcPattern, Locale.ENGLISH);
SimpleDateFormat tgtFormatter = new SimpleDateFormat(tgtPattern, Locale.ENGLISH);
return tgtFormatter.format(srcFormatter.parse(strDate));
}
And then call it with any pattern that you want:
System.out.println(formatDate("2020-10-16T18:04:59+0300", "yyyy-MM-dd'T'HH:mm:ssZ", "dd-MM-yyy HH:mm"));
Don’t write a method that converts a date and time from a string in one format to a string in a different format. In your program keep dates and times as proper date-time objects. Just like you don’t keep numbers and Boolean values in strings (I hope!) When you receive string input, parse into a date-time object at once. Only when you need to give string output, format into an appropriate string.
When I receive a string containing date, time and UTC offset, like yours does, I prefer to parse it into a OffsetDateTime so I get all the information. It’s easier to throw unneeded information away later than to invent the information that we neglected to parse. Also a LocalDate will not work for your purpose since it doesn’t contain time of day. So you cannot format one into 2020-10-16 18:04 format.
For parsing your string I would use:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffset("+HHmm", "Z")
.toFormatter();
String sourceData = "2020-10-16T18:04:59+0300";
OffsetDateTime dateTime = OffsetDateTime.parse(sourceData, formatter);
System.out.println(dateTime);
Output is:
2020-10-16T18:04:59+03:00
The definition of the formatter is longish but has the advantage of reusing predefined formatters for date and time.
For displaying a formatted date and time to the user, don’t you want to use the user’s time zone rather then the offset that happened to be in the string (+03:00 in your case)?
ZoneId zone = ZoneId.of("Antarctica/South_Pole");
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
String formatted = dateTime.atZoneSameInstant(zone).format(newFormatter);
System.out.println(formatted);
17-10-2020 04:04
What went wrong in your code?
As others have said, yyyy-MM-dd'T'HH:mm:ssZ in your format pattern string for parsing parses your entire date-time string of 2020-10-16T18:04:59+0300 nicely. The ''e at the end of the format pattern is the culprit. This would require an additional single quote (apostrophe) and the number of the day of the week to be present (pattern letter e is for localized day of week). Since Java had successfully parsed 24 chars and then failed to parse an apostrophe, it threw the exception mentioning thst the string could not be parsed at index 24.

Not able to parse String to Java Date

I have a string "2017-01-03T02:20:52+00:00" I want to convert into a LocalDateTime.
I tried the code below
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
public class HelloWorld{
public static void main(String []args){
System.out.println("Hello World");
String date = "2009-07-16T19:20:30-05:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime dateTime = LocalDateTime.parse(date, inputFormatter);
System.out.println(dateTime);
}
}
I tried various pattern but every time I am getting below error:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2009-07-16T19:20:30-05:00' could not be parsed at index 19
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at HelloWorld.main(HelloWorld.java:11)
A single Z does not allow : in the timezone. Use ZZZZZ (five Z) for the extended format.
The format of your date String is incorrect
Change it like so:
String date = "2009-07-16T19:20:30-0500";
Note the change before the timezone.
If you want to keep your date format, you can use this pattern:
String pattern = "yyyy-MM-dd'T'HH:mm:ssXXX";
try this:
String date = "2009-07-16T19:20:30-0500";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
or
String date = "2009-07-16T19:20:30-05:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssz";

How do I convert a DateTime with the GMT offset to UTC in Java?

I receive this DateTime from a payload: 2016-09-18T11:00:00.000-04:00.
I want to convert it to UTC. I know I just need to take the offset and modify the hours based on that, but I can't find the syntax to do this using the input in the format it is given to me.
Expected Result: 2016-09-18T15:00:00.000
Your input is in ISO format, so with Java 8+ it's fairly simple:
OffsetDateTime dateTime = OffsetDateTime.parse("2016-09-18T11:00:00.000-04:00");
OffsetDateTime utc = dateTime.withOffsetSameInstant(ZoneOffset.UTC); //2016-09-18T15:00Z
I was able to do this using SimpleDateFormat:
public static void main(String[] args) throws Exception {
SimpleDateFormat iso_8601_format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = iso_8601_format.parse("2016-09-18T11:00:00.000-04:00");
iso_8601_format.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(iso_8601_format.format(date));
}
This results in the following output:
2016-09-18T15:00:00.000Z
The literal 'Z' at the end is indicative of "Z"ero offset, or UTC. You could manually strip that off if you need to, but if you are using ISO 8601 as your format of choice, either is valid.

formatting string into dateformat with time offset

I need to convert a string into a Joda DateTime object, but the code I am using is not doing the conversion correct. My input is 20140722101846-0700, which should convert to something not unlike 2014-07-22T10:18:46-0700. Here is my code, followed by the incorrect output:
String myet = "20140722101846-0700"
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddhhmmss-hhmm");
DateTime mydt = dtf.parseDateTime(myet);
The resulting (incorrect) output is: 2014-07-22T07:00:46.000-07:00
How can I fix the code above so that is outputs a correct date?
Your DateTimeFormat doesn't have the correct symbols.
M is for month
m is for minutes
Z is used for the time zone offset (-0700)
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddhhmmssZ");

Categories