MM-dd-yyyy and yyyy-MM-dd date patterns in java



  •  Hi,

     Why SimpleDateFormat is not able to distinguish between  "MM-dd-yyyy" and  "yyyy-MM-dd" date patterns.

    private static String[] DATE_PATTERNS = { "MM-dd-yyyy",    "yyyy-MM-dd" };
        private static SimpleDateFormat formatter = new SimpleDateFormat();

        public static void main(String[] args) {
            System.out.println(parse("2008-11-24"));
            System.out.println(parse("11-24-2008"));
        }

        public static Date parse(String dateString) {
            Date parsedDate = null;
            String newDateString = dateString;
            for (String element : DATE_PATTERNS) {
                try {
                    //System.out.println("trying pattern: " + element);
                    formatter.applyPattern(element);
                    parsedDate = formatter.parse(newDateString);
                    break;
                } catch (Exception e) {
                }
            }
            return parsedDate;
        }

     

    Thanks,

    Ganesh



  •  Because SimpleDateFormat is stupid.  It has no regard for the fact that month should be between 1 and 12.  When it sees 2008, it figures that you mean 2008 months into the year 24, which is April of the year 191.  Consider these alternate dates, parsed with the same "MM-dd-yyyy" format:

     

    Date String Date Returned
    "01-32-2009"Sun Feb 01 00:00:00 EST 2009
    "13-01-2009"Fri Jan 01 00:00:00 EST 2010
    "-1-01-2009"Sat Nov 01 00:00:00 EDT 2008

    Are you starting to get the picture? SimpleDateFormat is, just as the name implies, simple. Frankly, Java's entire Date/Time system is a barrel of WTFs. Joda Time isn't perfect, but it's an improvement.



  • @bstorer said:

     Because SimpleDateFormat is stupid.  It has no regard for the fact that month should be between 1 and 12.

     

     

    But, what if you are one of the 17 people not using GregorianCalendar?



  • @tster said:

    @bstorer said:

     Because SimpleDateFormat is stupid.  It has no regard for the fact that month should be between 1 and 12.

     

     

    But, what if you are one of the 17 people not using GregorianCalendar?

    Well, you're in luck, then!  Just create a Locale object representing your backward language and country, pass it to the SimpleDateFormat constructor, and it'll automatically know that "13-13-2009" isn't January 13, 2010, but Smarch 13, 2009.

    And it'll still wrap around, so if the French Republican Calendar comes back into vogue (and it's only a matter of time), SimpleDateFormat will know that "9-76-217" is actually Thermidor 16, CCXVII!  Hey, that's today's date!  Thanks, Java!

    Jeez, is it Guimauve already?!  Seems like just yesterday it was Luzerne.  My how times flies.



  •  Thanks a lot for your replies.

    I tried to use locate object as per below, but it wont worked for above program.

    Locale locale = new Locale("EN","US");
    SimpleDateFormat formatter = new SimpleDateFormat("",locale);

    Please let me know if I am missing anything.

    Thanks,

    Ganesh



  • @gd.ganesh said:

     Thanks a lot for your replies.

    I tried to use locate object as per below, but it wont worked for above program.

    Locale locale = new Locale("EN","US");
    SimpleDateFormat formatter = new SimpleDateFormat("",locale);

    Please let me know if I am missing anything.

    Thanks,

    Ganesh

    Nothing you can do will make SimpleDateFormat do what you want.  That's just how it works.  As I said above, you should consider switching to Joda Time.  For example, this code:

    import org.joda.time.format.*;
    import org.joda.time.DateTime;
    

    public class JodaTimeDateFormat {
    private static DateTimeFormatter[] DATE_FORMATTERS = { DateTimeFormat.forPattern("MM-d-yyyy"), DateTimeFormat.forPattern("yyyy-MM-dd") };

    public static void main(String[] args) {
    System.out.println(parse("2008-11-24"));
    System.out.println(parse("11-24-2008"));
    }

    public static DateTime parse(String dateString) {
        DateTime parsedDate = null;
    for (DateTimeFormatter formatter : DATE_FORMATTERS) {
            try {
                //System.out.println("trying pattern: " + element);
                parsedDate = formatter.parseDateTime(dateString);
                break;
            } catch (Exception e) {
            }
        }
        return parsedDate;
    }
    

    }

    gives you this output:

    $ java -cp "joda-time-1.6.jar;." JodaTimeDateParse
    2008-11-24T00:00:00.000-05:00
    2008-11-24T00:00:00.000-05:00
    


  • Re: java.text.SimpleDateFormat

    I don't see a problem with SimpleDateFormat; it doesn't try to guess, it tries to parse given the format string. If you say MM-dd-yyyy but give it 2008-11-24, you just told it month 2008. The following works as expected.

    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    
    public class SimpleDateFormatTest {
    
    	public static void main(String[] args) throws java.text.ParseException {
    
    		DateFormat dfUSA = new SimpleDateFormat("MM/dd/yyyy");
    		System.out.println(dfUSA.parse("11/24/2008"));
    
    		DateFormat dfISO = new SimpleDateFormat("yyyy-MM-dd");
    		System.out.println(dfISO.parse("2008-11-24"));
    
    	}
    
    }
    

    which outputs

    Mon Nov 24 00:00:00 EST 2008
    Mon Nov 24 00:00:00 EST 2008
    

    (I like keeping a DateFormat to a single date format, rather than changing the format string).


Log in to reply