What\'s wrong with the following code? It throws a ParseException with error offset 0.
final DateFormat df = new SimpleDateFormat(\"EEE MMM dd HH:mm:ss yyyy\");
Is your locale "EN"
? If you use English names for the date, make sure you are using that locale
SimpleDateFormat
or DateTimeFormatter
without a Locale
Since the given date-time is in English, you should use Locale.ENGLISH
with your date-time parser; otherwise the parsing will fail in a system (computer, phone etc.) which is using a non-English type of locale.
Also, note that the date-time API of java.util
and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
Demo:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String strDateTime = "Thu Jan 23 14:24:47 2014";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss uuuu", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
System.out.println(ldt);
}
}
Output:
2014-01-23T14:24:47
By default, DateTimeFormatter#ofPattern uses the default FORMAT locale which the JVM sets during startup based on the host environment. Same is the case with SimpleDateFormat. I have tried to illustrate the problem through the following demo:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String strDateTime = "Thu Jan 23 14:24:47 2014";
DateTimeFormatter dtfWithDefaultLocale = null;
System.out.println("JVM's Locale: " + Locale.getDefault());
// Using DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss uuuu");
System.out.println("DateTimeFormatter's Locale: " + dtfWithDefaultLocale.getLocale());
System.out.println(
"Parsed with JVM's default locale: " + LocalDateTime.parse(strDateTime, dtfWithDefaultLocale));
// Setting the JVM's default locale to Locale.FRANCE
Locale.setDefault(Locale.FRANCE);
// Using DateTimeFormatter with Locale.ENGLISH explicitly (recommended)
DateTimeFormatter dtfWithEnglishLocale = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss uuuu", Locale.ENGLISH);
System.out.println("JVM's Locale: " + Locale.getDefault());
System.out.println("DateTimeFormatter's Locale: " + dtfWithEnglishLocale.getLocale());
LocalDateTime zdt = LocalDateTime.parse(strDateTime, dtfWithEnglishLocale);
System.out.println("Parsed with Locale.ENGLISH: " + zdt);
System.out.println("JVM's Locale: " + Locale.getDefault());
// Using DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss uuuu");
System.out.println("DateTimeFormatter's Locale: " + dtfWithDefaultLocale.getLocale());
System.out.println(
"Parsed with JVM's default locale: " + LocalDateTime.parse(strDateTime, dtfWithDefaultLocale));
}
}
Output:
JVM's Locale: en_GB
DateTimeFormatter's Locale: en_GB
Parsed with JVM's default locale: 2014-01-23T14:24:47
JVM's Locale: fr_FR
DateTimeFormatter's Locale: en
Parsed with Locale.ENGLISH: 2014-01-23T14:24:47
JVM's Locale: fr_FR
DateTimeFormatter's Locale: fr_FR
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Thu Jan 23 14:24:47 2014' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at Main.main(Main.java:33)
The following demo, using SimpleDateFormat
, is just for the sake of completeness:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
final String strDateTime = "Thu Jan 23 14:24:47 2014";
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", Locale.ENGLISH);
Date date = sdf.parse(strDateTime);
System.out.println(date);
}
}
Output:
Thu Jan 23 14:24:47 GMT 2014
SimpleDateFormat is absolutely locale-sensitive. Certain fields, like hours and minutes, are locale-independent.
SimpleDateFormat
also supports localized date and time pattern strings. In these strings, the pattern letters described above may be replaced with other, locale dependent, pattern letters.SimpleDateFormat
does not deal with the localization of text other than the pattern letters; that's up to the client of the class.
Or, you can use the localization-friendly DateFormat#getDateInstance() factory method instead, since:
public SimpleDateFormat(String pattern, Locale locale)
Constructs a
SimpleDateFormat
using the given pattern and the default date format symbols for the given locale. Note: This constructor may not support all locales. For full coverage, use the factory methods in the DateFormat class.
Source: https://stackoverflow.com/a/5174712/2591612
If you don't specify a Locale
to the formatter when you construct it, it uses your default Locale
which apparently doesn't spell days and months in English.
So specify one to the formatter that does.
final DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", Locale.UK);