Date formatting parse error Java - java

I want to format a date from Sun Apr 10 07:05:45 MDT 2017 to 2017-04-10T07:05:45.24Z.
I am using the following:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE-LLL-dd H:mm:sszuuuu");
formatter.parse(date);
date is in the format given above.
But I am getting a parse error at index 3

There are multiple issues. The correct pattern is "EEE MMM dd HH:mm:ss z uuuu"
need to use M instead of L - I'm investigating why at the moment. See DateTimeFormatter month pattern letter "L" fails. If you do a .format("LLL") it returns 4, as in 4th month.
need to use spaces instead of -
need spaces between s, z and uuuu
need to use HH not H
April 10th was a Monday, not a Sunday
See this example code run live at IdeOne.com.
String input = "Mon Apr 10 07:05:45 MDT 2017" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss z uuuu" , Locale.US );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
zdt.toString(): 2017-04-10T07:05:45-06:00[America/Denver]

What's "L"? Try "MMM" for month abbrev:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("EEE-MMM-dd H:mm:sszuuuu");

Related

Parse datetime with offset string to LocalDateTime

I am trying to parse following datetime String to LocalDateTimeObject, however I am not able to identify the format of the datetime string.
Sat, 09 Oct 2021 02:10:23 -0400
String s = "Sat, 09 Oct 2021 02:10:23 -0400";
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
LocalDateTime dateTime = LocalDateTime.parse(s, formatter);
System.out.println(dateTime);
How should I determine the pattern of the above string?
You should first check if the date string matches any of the Predefined Formatters.
If not, then you have to make your own Formatter using .ofPattern(String pattern) or .ofPattern(String pattern, Locale locale). To do this, you can see all the defined pattern letters here in section Patterns for Formatting and Parsing.
For your example, you can use either DateTimeFormatter.RFC_1123_DATE_TIME:
DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime dateTime = OffsetDateTime.parse(s, formatted);
or:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z");
OffsetDateTime dateTime = OffsetDateTime.parse(s, formatted);
Note that OffsetDateTime is used to represent the date-time with an offset from UTC.
Symbol Meaning
------ -------
E day-of-week
d day-of-month
M month-of-year
y year-of-era
H hour-of-day (0-23)
m minute-of-hour
s second-of-minute
Z zone-offset

Java parse date from string with GMT string

I have the following date string Tue Feb 04 2020 16:11:25 GMT+0200 (IST) where I'm trying to convert into date time using the following code:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
And I got the following exception:
Text Tue Feb 04 2020 16:11:25 GMT+0200 (IST) could not be parsed at index 28
I look at the following SO question Java string to date conversion and I see that
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
So why I got the exception?
The following pattern works.
"E MMM d u H:m:s 'GMT'Z (z)"
You can replace Z with x or X for the same result.
You can spell it out, if you want, but it is not necessary.
"EEE MMM dd uuuu HH:mm:ss 'GMT'ZZZ (zzz)"
You should parse that input to an OffsetDateTime, since the input string includes a Date, a Time, and an Offset.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM d u H:m:s 'GMT'Z (z)", Locale.ENGLISH);
OffsetDateTime dateTime = OffsetDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
System.out.println(dateTime);
Output
2020-02-04T16:11:25+02:00
One of the reasons is that you are trying to parse a datetime String (date, time, zone and offset) to an object (LocalDate) that only stores year, month and day, nothing more.
Use a suitable class, say ZonedDateTime and adjust the parsing pattern a little:
you can't use the localized offset O because in a DateTimeFormatter it doesn't support the formatting your String has, which is GMT+0200 and the formatter supports GMT+8; GMT+08:00; UTC-08:00; only (mind the colon). Use a combination of an escaped GMT plus a regular offset symbol x
you have a single d but a representation of days that will always have two digits, so you need to use dd
you have to escape the brackets the zone abbreviation is enclosed in and I think a single z is sufficient for such an abbreviation
Considering all these aspects, you could parse the String as follows:
public static void main(String[] args) {
String parsePattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'x '('z')'";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePattern,
Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
System.out.println(zdt);
}
which then outputs (using the default formatter for ZonedDateTime)
2020-02-04T16:11:25+02:00[Asia/Jerusalem]
The problem here is the GMT+0200 if you use: GMT+02 it works.
But as already mentioned in the comments it is a little confusing that you use a variable called dateTime on something of the type LocalDate.
So your result will be only the date 2020-02-04 because LocalDate can only save this kind of data.
2 things - ZonedDateTime & missing ':' for 0
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)");
ZonedDateTime dateTime = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+02:00 (IST)", formatter);
This should work
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss 'GMT'Z (z)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
Do not use a fixed text for the timezone:
Do not use a fixed text (e.g. 'GMT') for the timezone as mentioned in the existing answers because that approach may fail for other locales.
The recommended solution:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Tue Feb 04 2020 16:11:25 GMT+0200 (IST)";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d u H:m:s VVZ (z)", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
Output:
2020-02-04T14:11:25Z[Atlantic/Reykjavik]
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
you wrote one d and you passed 04 you should write dd instead of d like the following
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);

Joda: parse string as DateTime with weird timezone format

Is there a valid joda DateTimeFormat for date strings like the following:
Mon, 23 Jul 2018 07:08:26 +0300 GMT
I have tried:
DateTimeFormatter FMT1 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z");
DateTimeFormatter FMT2 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss z");
DateTimeFormatter FMT3 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss z Z");
but none of these work.
I had a look in here https://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html and I cannot figure out a way to parse that date without having to change the string itself first.
Is there a way?
I take it that +0300 is the true offset and GMT is just there to say that +0300 is relative to GMT. Joda-Time supports apostrophes for delimiting constant text that shouldn’t be interpreted:
DateTimeFormatter formatter = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z 'GMT'");
DateTime dt = DateTime.parse("Mon, 23 Jul 2018 07:08:26 +0300 GMT", formatter);
System.out.println(dt);
Output on my computer in Europe/Copenhagen time zone:
2018-07-23T06:08:26.000+02:00
As an aside the idea of using a lowercase and an uppercase z wasn’t too bad. It works if you put them in the opposite order:
DateTimeFormatter formatter = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z z");
2018-07-23T04:08:26.000Z
I prefer the apostrophes, though. It’s hard for a reader to know what to expect from Z z.

Joda-Time DateTimeFormatter: get the correct output

I need to convert a Joda-Time DateTime into a String, in the following format:
Sat, 1 Jan 2011 00:00:00
I'm using this code:
DateTimeFormatter f = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss");
f.withLocale(Locale.US);
System.out.println(DateTime.now().toString(f));
My output is however:
wo, 20 jun. 2012 00:03:31
So the problems are:
The output is in Dutch instead of English ('wo' for 'wed')
The month has a period
How can I do this correctly?
DateTimeFormatter.withLocale returns a new DateTimeFormatter. So you need to do this:
f = f.withLocale(Locale.US);
Alternatively (equivalently):
DateTimeFormatter f = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss").withLocale(Locale.US);

parsing dates with variable spaces

I am using Joda to parse dates and have a format where leading zeros are not used, e.g.:
Mon Nov 20 14:40:36 2006
Mon Nov 6 14:40:36 2006
Note that the dayOfMonth field is left-padded with a blank.
Currently I seem to have to use two different formats and reparse if one fails
"EEE MMM dd HH:mm:ss yyyy"
"EEE MMM d HH:mm:ss yyyy"
Is there a single format (or an API switch) which deals with both cases? (is the answer the same for SimpleDateFormat - which I don't use?)
java.time and format pattern letter p
Here’s the modern answer, using java.time, the successor of Joda-Time.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM ppd HH:mm:ss uuuu", Locale.ENGLISH);
String[] stringsToParse = {
"Mon Nov 20 14:40:36 2006",
"Mon Nov 6 14:40:36 2006"
};
for (String dateTimeString : stringsToParse) {
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
}
Output:
2006-11-20T14:40:36
2006-11-06T14:40:36
To DateTimeFormatter.ofPattern format letter p means padding with spaces on the left. pp means padding to two position. It can be used for both formatting and — as here — parsing.
I know you asked about Joda-Time. The Joda-Time home page says:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of DateTimeFormatter
Joda-Time - Home
I have just created a quick program to check this -
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy");
try {
String source1 = "Mon Nov 20 14:40:36 2006";
Date d1 = sdf.parse(source1);
String source2 = "Mon Nov 6 14:40:36 2006";
Date d2 = sdf.parse(source2);
String res1 = sdf.format(d1);
String res2 = sdf.format(d2);
System.out.println(source1 +"="+ res1);
System.out.println(source2 +"="+ res2);
} catch (ParseException e) {
e.printStackTrace();
}
The output from this is -
Mon Nov 20 14:40:36 2006=Mon Nov 20 14:40:36 2006
Mon Nov 6 14:40:36 2006=Mon Nov 6 14:40:36 2006
So, even though source2 has the extra space, it is still parsed by
EEE MMM d HH:mm:ss yyyy
Hope that helps
I tried using a single 'd' as suggested above in logstash 1.1.1 but it still complained about a malformed date when a single digit day with an extra leading space was parsed. The following logstash rules did work.
timestamp => [ "MMM dd HH:mm:ss", "MMM d HH:mm:ss" ]
It didn't matter which order the two date formats were in. No more warnings were output once I added both formats.

Categories

Resources