I get the following error:
´java.text.ParseException: Unparseable date: "Aug 31 09:53:19 2011"´ with this format: new SimpleDateFormat("MMM dd HH:mm:ss yyyy");
Does anyone see the problem?
I get the following error:
´java.text.ParseException: Unparseable date: "Aug 31 09:53:19 2011"´ with this format: new SimpleDateFormat("MMM dd HH:mm:ss yyyy");
Does anyone see the problem?
Make sure you're using the correct locale. (The SimpleDateFormat(String)
constructor uses the system default locale, which may not be the one you want to use.)
This works fine on my machine:
String input = "Aug 31 09:53:19 2011";
DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US);
System.out.println(df.parseObject(input));
(While using Locale.FRENCH
for instance, results in a ParseException
.)
The format itself is OK for the input you gave. But you might get this error if your default locale is set to something where "Aug" is not a valid abbreviation of a month name. Try using for example to Locale.US
and you'll see that it will work:
DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US);
Date date = df.parse("Aug 31 09:53:19 2011");
2017-08-01T08:32:38.5544401-05:00
and this is the pattern yyyy-MM-dd'T'HH:mm:ssz
. and i'm getting the exception. Please help –
Politian SimpleDateFormat
cannot deal with 7 digits of fractional seconds. See: #12001173 –
Ifc String actualFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSz";
and this is the result Orignal Date: 2017-08-01T08:50:36.8762641-05:00 Converted Time: 18:50:36
Is it correct? –
Politian 08:50:36.8762641
this figure 36.8762641? –
Politian yyyy-MM-dd'T'HH:mm:ss
–
Politian Locale
, to determine human language and cultural norms used in translating the name of month.Contrived example:
LocalDateTime.parse( // Parse input text as a `LocalDateTime` lacking any concept of time zone or offset-from-UTC.
"Aug 31 09:53:19 2011" ,
DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss yyyy" ) // Specify formatting pattern to match input string.
.withLocale( Locale.US ) // The `Locale` determines the human language and cultural norms used in translating the input text.
) // Returns a `LocalDateTime` object.
The other two answers by aioobe and by Jesper are both correct: Implicitly using a Locale
with a human language that does not match the language of your input text.
This Answer explains a new way of doing the job. Also, the other Answers do not address the crucial issue of time zone.
Fast forward a few years later from this posting, and we now have the new java.time package built into Java 8 and later. These new classes supplant the old java.util.Date/.Calendar & SimpleDateFormat classes. Those old classes have proven to be troublesome, confusing, and flawed.
Define the data to be parsed and its format.
String input = "Aug 31 09:53:19 2011";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss uuuu" );
If not specified, the DateTimeFormatter
is assigned the Locale
that is currently the default in the JVM. That default can change at any moment, even during runtime(!). So always specify the desired/expected Locale
.
formatter = formatter.withLocale( Locale.US ); // Or Locale.UK, Locale.CANADA_FRENCH, etc.
Given that the input lacks any time zone or offset-from-UTC information, parse as a LocalDateTime
.
LocalDateTime ldt = LocalDateTime.parse( input , formatter );
If from the context you know the intended offset-from-UTC or a time zone for this date-time value, assign it.
If UTC, use the ZoneOffset.UTC
constant to get a OffsetDateTime
object.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
A time zone is an offset-from-UTC plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Use proper time zone names, never the 3-4 letter abbreviations.
ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId_Montreal );
This human language element was the key missing piece to answer the Question. Specifying the correct Locale
for the human language matching the language of your input string solves that problem.
But note that the time zone is also critical; the other answers ignored this issue thereby implicitly using the JVM’s current default time zone. That is not advisable, as it depends on the host operating system as an initial default value (so may vary) and furthermore any code in any thread of any app within the JVM can change the JVM’s current default time zone during runtime. Better to specify the desired/expected time zone than rely implicitly on default.
Note the syntax. These classes are designed to be immutable. So rather than modifying (mutating) an object, a fresh new object is created based on the old object’s values. This means we are not affecting the DateTimeFormatter
object defined above and held in the formatter
variable (object reference). We are creating, using, and discarding a new DateTimeFormatter object (actually, two new objects) within this line of code.
The documentation suggests an alternative way to parse a string is to call the parse
method where you pass a method reference (new in Java 8) from the class of the kind of result you desire (as the TemporalQuery
): ZonedDateTime::from
, LocalDateTime::from
, LocalDate::from
, and so on.
ZonedDateTime zdt = formatter.withZone( zoneId_Montreal ).withLocale( Locale.ENGLISH ).parse( input, ZonedDateTime :: from );
For demonstration, let's turn around and create a String representation of that ZonedDateTime
value but in Québécois French.
String output = formatter.withLocale( Locale.CANADA_FRENCH ).format( zdt );
Even better, let’s localize rather than hard-code a particular format.
String outputLocalized = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ).format( zdt );
Dump to console.
System.out.println( "input: " + input );
System.out.println( "formatter: " + formatter );
System.out.println( "zdt: " + zdt );
System.out.println( "output: " + output );
System.out.println( "outputLocalized: " + outputLocalized );
When run.
input: Aug 31 09:53:19 2011
formatter: Text(MonthOfYear,SHORT)' 'Value(DayOfMonth,2)' 'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)' 'Value(YearOfEra,4,19,EXCEEDS_PAD)
zdt: 2011-08-31T09:53:19-04:00[America/Montreal]
output: août 31 09:53:19 2011
outputLocalized: mercredi 31 août 2011 9 h 53 EDT
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
© 2022 - 2024 — McMap. All rights reserved.
Locale
and the time zone in your date-time work rather than rely implicitly on the JVM’s current default. Both can change at any moment during runtime. – Hookedjava.util.Date
,java.util.Calendar
, andjava.text.SimpleDateFormat
are now legacy, supplanted by the java.time classes built into Java 8 and later. See Tutorial by Oracle. – Hooked