SimpleDateFormat ignoring month when parsing
Try:
"yyyy-MM-dd'T'HH:mm:ss"
MM
means month. mm
means minutes. See the documentation for SimpleDateFormat
for more details of the supported date and time patterns.
Java SimpleDateFormat Seemingly Ignoring Month and Day
I think your pattern is a little off. I'm suprised you're not seeing an IllegalArgumentException. Try using the following pattern with lower case y's and see if that resolves your issue:
SimpleDateFormat sqlFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Why does SimpleDateFormat.parse not throw an exception here?
Any idea what's wrong?
This is one of the places where SimpleDateFormat
gets really troublesome. When trying to parse 1980-04-25
using the pattern yyyyMMdd
it parses 1980
as year as expected, then -0
as month since it was supposed to be two characters, then 4
as day of month even though it was supposed to be two characters too. It ignores the -25
because it has done parsing.
A SimpleDateFormat
with standard settings also ignores the fact that there is no month -0
. It takes it as 0, so the month before January 1980, which is why you get December 1979.
SimpleDateFormat
is notoriously troublesome, and Date
is poorly designed too. Both are long outdated. I recommend you don’t use SimpleDateFormat
. Ever.
java.time
private static final String[] dateFormats
= "yyyyMMdd,yyyy/MM/dd,yyyy-MM-dd,dd/MM/yyyy,dd-MM-yyyy,dd-MMM-yyyy,yyyy MM dd"
.split(",");
public static LocalDate parseAllDateFormats(String date) {
if (date == null) {
return null;
}
for (String format : dateFormats) {
try {
System.out.println("trying " + format);
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
return LocalDate.parse(date, dateFormatter);
}
catch (DateTimeParseException e) {
// Ignore, try next format
}
}
return null;
}
Let’s try it with your example string:
System.out.println(parseAllDateFormats("1980-04-25"));
Output is the expected:
trying yyyyMMdd
trying yyyy/MM/dd
trying yyyy-MM-dd
1980-04-25
I am using java.time, the modern Java date and time API. Compared to the old date-time classes it is so much nicer to work with. The modern DateTimeFormatter
can resolve the parsed values into a date in three styles: strict, smart and lenient. Smart is the default where it will only accept month number from 1 through 12. Also LocalDate.parse
will insist on parsing the entire string, or it will throw an exception.
Compared to your code I also made a couple of minor modifications. For most purposes I would have made an array of DateTimeFormatter
(not of String
), but it would not have allowed me to print trying yyyyMMdd
, so here I didn’t. I put curly braces in the first if
statement. I specified locale on the formatter because month abbreviations differ between languages and I want to control which language is used. I catch the specific DateTimeParseException
and I added a comment why I ignore it because otherwise ignoring an exception is a bad, bad thing. At the bottom of your method you should also consider throwing an exception if no format worked rather than returning null
.
Java 6
be aware I'm stuck with java6 here.
- The java.time classes are built into Java 8 and later, as well as Android 26 and later.
- ✅ Most of the java.time functionality is back-ported to Java 6 & Java 7 in the ThreeTen-Backport project.
- Further adapted for earlier Android (<26) in ThreeTenABP. See How to use ThreeTenABP….
Links
- Related question: SimpleDateFormat giving wrong date instead of error
- Related question: SimpleDateFormat parse(string str) doesn't throw an exception when str = 2011/12/12Simpledateformat Ignoring Month When Parsinga?
- Oracle tutorial: Date Time explaining how to use java.time.
Simple date format reading month incorrectly
This is because DD
means day in year. You want dd
for day in month. See SimpleDateFormat Javadoc
I suggest you use HH
for 24 hour time.
SimpleDateFormat issue when parsing a String in ISO 8601 format
The date format passed to your SimpleDateFormat
is "dd/MM/yy"
, while the date you are trying to parse is of the format "yyyy-MM-dd"
. Try this instead:
Date login = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ").parse("2017-05-16 06:24:36-0700");
As a side note, depending on which version of Java you are using, I would recommend using the new java.time
package (JDK 1.8+) or the back port of that package (JDK 1.6+) instead of the outdated (no pun intended) Date
and/or Calendar
classes.
Instant login = Instant.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ").parse("2017-05-16 06:24:36-0700"));
SimpleDateFormat returns a strange value in java
Remember that 'm' means minutes and 'M' means months
http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Related Topics
Difference Between Volatile and Synchronized in Java
How to Make a JPA Onetoone Relation Lazy
How to Use Wait and Notify in Java Without Illegalmonitorstateexception
Org.Xml.Sax.Saxparseexception: Content Is Not Allowed in Prolog
Check Whether a String Is Not Null and Not Empty
How to Convert Byte Array to String and Vice Versa
How to Programmatically Compile and Instantiate a Java Class
Overriding Member Variables in Java ( Variable Hiding)
Java: Unresolved Compilation Problem
Which @Notnull Java Annotation Should I Use
Difference Between Statement and Preparedstatement
What Is the Memory Consumption of an Object in Java
List of Java Class File Format Major Version Numbers
Getting Hold of the Outer Class Object from the Inner Class Object
How Does the "Final" Keyword in Java Work (I Can Still Modify an Object.)
Difference Between Fetchtype Lazy and Eager in Java Persistence API