I need to parse any incoming date time string with a user specified locale and timezone to the sole pattern to properly store it in the database later:
String inputDatetime = "Mon Dec 21 21:18:37 GMT 2020";
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withLocale(Locale.getDefault()).withZone(ZoneOffset.UTC);
TemporalAccessor date = fmt.parse(inputDatetime);
But I get the following error:
java.time.format.DateTimeParseException: Text 'Mon Dec 21 21:18:37 GMT 2020' could not be parsed at index 0
What's the problem with this code?
Assuming that your database has got a
timestamp with time zonedatatype, this is what you should use for storing the date and time from your string. Your input string unambiguously defines a point in time, and so doestimestamp with time zone.Next you should not store the date-time as a string in a particular format that your database likes. Store proper date-time objects. Since JDBC 4.2 this means objects of types from java.time, the modern Java date and time API that you are already using. Then you don’t need to care about format. It’s all taken care of for you. If your database datatype is
timestamp with time zone, store anOffsetDateTimeinto that column. It instead it’stimestampwithout time zone ordatetime, instead store aLocalDateTime. The documentation of your JDBC driver should give you more details.What's the problem with this code?
I see more than one problem with your code.
yyyy-MM-dd HH:mm:ss, but your string clearly is not inyyyy-MM-dd HH:mm:ssformat. So this is bound to fail. More specifically the format string begins withyyyyfor year of era, for example 2020. So the formatter expects to find a four digit number for year at the beginning of your string. Instead it findsMonand throws the exception. The exception message informs us that the stringcould not be parsed at index 0. Index 0 is the beginning of the string, where theMonis. I am not sure, but it seems that you have been confusing input and output format. Converting a date-time from a string in one format to a string in a different format involves two operations:Locale.getDefault()will work on English-speaking devices and then suddenly fail when one day you run it on a device with a different language setting. So it’s a bad idea.TemporalAccessoris a low-level interface that we should seldom be using. Instead parse your string into aZonedDateTimesince it contains date, time and time zone (in a stringGMTcounts as a time zone).If you were to format the date-time to the format of your
DateTimeFormatter— which, as I said, I don’t think is what you should want — the following would work:Output: