Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat problems with 2 year date

I'm trying to understand two things:

  1. Why doesn't the following code throw an exception (since the SimpleDateFormat is not lenient)
  2. It doesn't throw an exception, but why is it parsing the year as 0013 (instead of using the rules here the +80:-20 years from today rule)

Here's the code

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class TestDate {
    public static void main(String[] args) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        format.setLenient(false);
        Date date = format.parse("01/01/13"); // Since this only has a 2 digit year, I would expect an exception to be thrown

        System.out.println(date); // Prints Sun Jan 01 00:00:00 GMT 13

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        System.out.println(cal.get(Calendar.YEAR)); // Prints 13
    }
}

If it makes a difference, I'm using java 1.6.0_38-b05 on Ubuntu

like image 754
John Farrelly Avatar asked Aug 08 '13 13:08

John Farrelly


People also ask

Is SimpleDateFormat deprecated?

Class SimpleDateFormat. Deprecated. A class for parsing and formatting dates with a given pattern, compatible with the Java 6 API.

Why is SimpleDateFormat not thread-safe?

2.2.Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally. So SimpleDateFormat instances are not thread-safe, and we should use them carefully in concurrent environments.

What can I use instead of SimpleDateFormat?

DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.

Is SimpleDateFormat case sensitive?

The formats are case-sensitive. Use yyyy for year, dd for day of month and MM for month. You need to read the javadoc of SimpleDateFormat more carefully, Take special care for lower-case and upper-case in the patterns.


2 Answers

SimpleDateFormat API:

For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

As for lenient, when it's set to false parse throws exception for invalid dates, eg 01/32/12, while in lenient mode this date is treated as 02/01/12. SimpleDateFormat uses Calendar internally, details about leniency can be found in Calendar API.

like image 54
Evgeniy Dorofeev Avatar answered Oct 06 '22 02:10

Evgeniy Dorofeev


Question 1. This is a partial duplicate of Why Does Java's SimpleDateFormat parse this. The second answer on the question answers this nicely. The crux of it is this:

Number: For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields. Year: During parsing, only strings consisting of exactly two digits […] will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern

Question 2. Look carefully: your input format is not the same as the format that you are passing to the function.

new SimpleDateFormat("dd/MM/yyyy");

vs.

format.parse("01/01/13");

Either parse to 01/01/2013 or use the date forat 'dd/MM/yy'.

like image 34
Kukanani Avatar answered Oct 06 '22 01:10

Kukanani