-2

Is this 00/00/00 a valid Date which is in MM/dd/yy format in Java?

I have tried this below sample code to see if the 00/00/00 is a valid one in Java. But, the date which is getting parsed is SUN Nov 30 00:00:00 IST 2.

public static void main(String[] args) {

System.out.println(new SimpleDateFormat("MM/dd/yy").parse("00/00/00"));

}

If not, how do I parse the Date string "00/00/00" in the format MM/dd/yy in Java?

The thing is I need to read the string 00/00/00, which is obtained in a text file. In this process, I am getting SUN Nov 30 00:00:00 IST 2 as output when I parsed that string using parse() method of SimpleDateFormat. But, I am expecting 0th Year, 0thDay, 0thMonth as output. Do you think this is possible?

Thanks for your time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • `Run as --> Java Application` thats all you need to do. – Abdullah Khan Jul 19 '17 at 14:15
  • 5
    Why do you need to parse `00/00/00` to a `Date`? And what would be month zero and day zero? I'm failing to see the point here... –  Jul 19 '17 at 14:16
  • 1
    0/0/0 is one month and one day before 1/1/0 so Nov 30 seems correct. – Henry Jul 19 '17 at 14:17
  • 2
    try with `simpleDateFormat.setLenient(false);`. By default, `SimpleDateFormat` tries its very best to be helpful. Sometimes it's *too* helpful, and happily parses gibberish dates like that – David Lavender Jul 19 '17 at 14:21
  • 4
    This sounds like an [XY problem](https://meta.stackexchange.com/a/66378/286538). `00/00/00` is not really a valid date. Why are you trying to parse it? Why not just detect that it is equal to `00/00/00` as a string and then use a predetermined value or behavior instead? Please explain the context of the question. – RealSkeptic Jul 19 '17 at 14:27
  • 3
    No it’s not a valid date. There is no year 0, no 0th month and no 0th day in a month. `SimpleDateFormat` in lenient mode (see @MrSpoon’s comment) is lenient enough to parse it anyway. – Ole V.V. Jul 19 '17 at 14:30
  • 1
    @Henry, to explain a little more fully, 0/0/0 is parsed as 1 year 1 month 1 day before 1/1/1 AD, where the year before year 1 is year 1 BC, so year 2 (BC) seems correct too (if correctness makes sense here). – Ole V.V. Jul 19 '17 at 14:33
  • DilipKumarC, do you know what result you want? As I said, there is no such date in the calendar, so there is no way to obtain a date that will print back as 00/00/00. – Ole V.V. Jul 19 '17 at 14:36
  • Thank you every one. The thing is I need to read the string 00/00/00 which is obtained in a text file. In this process, I am getting SUN Nov 30 00:00:00 IST 2 as output when I parsed that string using parse() method of SimpleDateFormat. But, I am expecting 0th Year, 0thDay, 0thMonth as output. Do you think this is possible? – DilipKumarC Jul 19 '17 at 15:29
  • 2
    As the comments above have already said, that's not possible. The best you can do is check if the `String` is `00/00/00` and handle it separately - or try to parse with the `setLenient(false)` option and catch the exception. –  Jul 19 '17 at 15:46
  • Third, but poorer, option, check if resulting date equals SUN Nov 30 00:00:00 IST 2 and handle this case specially. Note that the 2 in the end refers to year 2 *before* the common era (BCE). – Ole V.V. Jul 19 '17 at 17:34
  • As an aside, consider using the modern `DateTimeFormatter` in preference to the outdated `SimpleDateFormat`. – Ole V.V. Jul 19 '17 at 17:40
  • As to why someone would be generating/parsing the string `"00/00/00"`, it *might* be a misguided attempt to represent a ‘null’-type of value, an unknown date. – Basil Bourque Jul 19 '17 at 18:42
  • 1
    Why the down-votes? This seems like a legitimate question to me. A quick check did not find any duplicate questions about a date-only string value of `00/00/00`. – Basil Bourque Jul 19 '17 at 19:19

2 Answers2

1

Hugo already said it:

The best you can do is check if the String is 00/00/00 and handle it separately - or try to parse with the setLenient(false) option and catch the exception.

What I want to do here is show you how you can skip the outdated (and quite often troublesome) SimpleDateFormat class and follow the suggestion using the modern Java date and time API.

My preferred solution is checking the date string explicitly:

    if (dateFromFile.equals("00/00/00")) {
        System.out.println("0000-00-00");
    } else {
        System.out.println(LocalDate.parse(dateFromFile, 
                                           DateTimeFormatter.ofPattern("MM/dd/yy")));
    }

I am assuming your string is in a String dateFromFile.

The other option is you try to parse the string and catch the exception (the modern DateTimeFormatter isn’t lenient per default):

    try {
        System.out.println(LocalDate.parse(dateFromFile, 
                   DateTimeFormatter.ofPattern("MM/dd/yy")));
    } catch (DateTimeParseException dtpe) {
        System.out.println("0000-00-00");
    }

One potential advantage is it will also catch cases where the string contains zeroes for unknown fields but isn’t literally equal to 00/00/00 — for example 07/00/17 or 0/0/0.

Third and poorest option, parse leniently and compare to the date that comes out of 00/00/00:

    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("MM/dd/yy")
            .withResolverStyle(ResolverStyle.LENIENT);
    LocalDate unknownDateParsed = LocalDate.of(1999, Month.NOVEMBER, 30);
    LocalDate date = LocalDate.parse(dateFromFile, parseFormatter);
    if (date.equals(unknownDateParsed)) {
        System.out.println("0000-00-00");
    } else {
        System.out.println(date);
    }

DateTimeFormatter assumes 2000–2099 when you give it a two-digit year, so 00/00/00 becomes November 30, 1999 because it is 1 month 1 day before 01/01/2000.

One issue with the last approach is poorer validation: it will let other incorrect dates like for example 05/35/17 or 13/32/45 pass without notice.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

Treat such input as an error

As others have said, there is no month zero nor day-of-month zero in modern Western chronology.

Therefore, I would treat such input as an error condition, and reject the input.

DateTimeFormatter f = DateTimeFormatter. ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US ) ;
…

if( input.equals( "00/00/00" ) ) { 
    … // handle error 
} else {
    LocalDate ld = LocalDate.parse( input , f ) ; 
}

You should ask the source of the data if this is an error or a special value. Perhaps it is meant to be a stand-in for a “null”-type of value, an unknown date. If so, I would suggest an alternative. For example, the word “unknown” or a designated date value. One possible such value, assuming your known values are more recent, might be the common epoch reference date of 1970-01-01. For date-time, use the constant Instant.EPOCH value, 1970-01-01T00:00:00Z.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154