0

I am very confused in the below code. Even after passing the correct dateformat for parsing the entire date, time and timezone, why java is ignoring the information beyond minutes.

I have a list of date formatters as my incoming date can come in any formats. I want all dates to be parsed with whatever information was provided.

But I see that in output, all the information for seconds, milliseconds and timezone is ignored.

public class DateValidator {


 final static DateFormat dateFormat_hour = new SimpleDateFormat("yyyy-MM-dd,HH");
    final static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static final DateFormat DATE_TIMESTAMP_MIN= new SimpleDateFormat("yyyy-MM-dd,HH:mm");
    private static final DateFormat DATE_TIMESTAMP_SEC = new SimpleDateFormat("yyyy-MM-dd,HH:mm:ss");
private static final DateFormat DATE_TIMESTAMP_MILLISEC = new SimpleDateFormat("yyyy-MM-dd,HH:mm:ss.SSS");

private static final DateFormat DATE_TIMESTAMP_ZONE_OFFSET = new SimpleDateFormat("yyyy-MM-dd,HH:mm:ss.SSSZ");

/**
 * the list formatter which will store all date formats which are possible in incoming date.
 */
private static final List<DateFormat> DATE_FORMATTER_LIST;
static {
    DATE_FORMATTER_LIST = Arrays.asList(DATE_TIMESTAMP_MIN, DATE_TIMESTAMP_SEC, DATE_TIMESTAMP_MILLISEC, DATE_TIMESTAMP_ZONE_OFFSET,dateFormat_hour,dateFormat);
}

/**
 * validating the date type is valid or not.
 *
 * @param dateString the date string
 * @return true or false
 */
public static Date parseDate(String dateString) {

    if (dateString == null || dateString.isEmpty()) {
        return null;
    }

    for (DateFormat pattern : DATE_FORMATTER_LIST) {

        try {
            return pattern.parse(dateString);

        } catch (ParseException pe) {
           //ignore
        }
    }
    System.out.println(("Error while parsing date , date not in valid format"));
    return null;
}

public static void main(String args[]){
 
    System.out.println(new Date(parseDate("2020-11-01,01:01:05.555+0300").getTime()));//****no, no
    System.out.println(new Date(parseDate("2020-11-01,01:01:05.555+0000").getTime()));//****no, no
    System.out.println(new Date(parseDate("2020-11-01,01:01:05.000+0000").getTime()));//****no, no
    System.out.println(new Date(parseDate("2020-11-01,01:01:59.000").getTime()));//****no, no
    System.out.println(new Date(parseDate("2020-11-01,01:01:05").getTime()));//****no, no
    System.out.println(new Date(parseDate("2020-11-01,01:01").getTime()));//*****good
    System.out.println(new Date(parseDate("2020-11-01,01").getTime()));//*****good
    System.out.println(new Date(parseDate("2020-11-01").getTime()));//*****good
}

}

Output is :

Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:01:00 IST 2020
Sun Nov 01 01:00:00 IST 2020
Sun Nov 01 00:00:00 IST 2020
Onki
  • 1,879
  • 6
  • 38
  • 58
  • 1
    probably because you use this formatter: new SimpleDateFormat("yyyy-MM-dd,HH:mm"); – Stultuske Apr 11 '22 at 06:53
  • 3
    Stop using the outDated `java.util.Date` and `SimpleDateFormat` classes. use the modern `java.time.*` API – Jens Apr 11 '22 at 06:56
  • 1
    The first 6 inputs are been successfully parsed by `yyyy-MM-dd,HH:mm`, then it's `yyyy-MM-dd,HH`, `yyyy-MM-dd` - seriosly, time to put `Date` and `DateFormatter` to bed and make use of the `java.time` API instead – MadProgrammer Apr 11 '22 at 06:58
  • BTW: Take care of java naming conventions. *static final* variable names should be upper case – Jens Apr 11 '22 at 06:58
  • 1
    Check out [this example](https://stackoverflow.com/questions/71535387/validating-date-taken-in-from-user-in-3-different-formats/71535714#71535714), it will use a series of formatters to test that value can be parsed BUT also checks that the resulting value is the same when it's formatted (plus some regular expression thrown in) as well as [this example](https://stackoverflow.com/questions/20231539/java-check-the-date-format-of-current-string-is-according-to-required-format-or/20232680#20232680) – MadProgrammer Apr 11 '22 at 07:02
  • A solution that I find good is to use a formatter defined as `new DateTimeFormatterBuilder() .appendPattern("uuuu-MM-dd[,HH[:mm[:ss[.SSS]]][xx]]") .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) .toFormatter() .withZone(ZoneId.of("Asia/Tel_Aviv"))` and parse into a `ZonedDateTime`. It works for all of your example strings. – Ole V.V. Apr 11 '22 at 08:31
  • 1
    What happens when you try to parse `2020-11-01,01:01:05.555+0300` is that `2020-11-01,01:01` is parsed by the first formatter using the pattern `yyyy-MM-dd,HH:mm`, and the rest of the string is ignored. The other formatters are not tried. Yes, this is how confusing `SimpleDateFormat` is (and it’s very far from the only problem with it). I agree with the others: drop trying to make that class behave. – Ole V.V. Apr 11 '22 at 08:37
  • Related: [SimpleDateFormat leniency leads to unexpected behavior](https://stackoverflow.com/questions/50746771/simpledateformat-leniency-leads-to-unexpected-behavior) – Ole V.V. Apr 11 '22 at 12:33

0 Answers0