3

I'm going to validate a simple time date format (yyyy-MM-dd'T'HH:mm:ss) as follows. This implementation works for most major validations but somehow I found some validations doesn't seems to be working. such as if you enter 2014-09-11T03:27:54kanmsdklnasd , 2014-09-11T03:27:54234243 it doesn't validate. Can you please point out my code error?

code

String timestamp = "2014-09-11T03:27:54";
SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try{
    format.parse(timestamp);
    LOG.info("Timestamp is a valid format");
}
catch(ParseException e)
{
    return ssoResponse;
}
icza
  • 389,944
  • 63
  • 907
  • 827
Amila Iddamalgoda
  • 4,166
  • 11
  • 46
  • 85

3 Answers3

4

SimpleDateFormat.parse() (which comes from DateFormat.parse()) cannot be used for full-string validation because quoting from its javadoc:

The method may not use the entire text of the given string.

Instead you can use the DateFormat.parse(String source, ParsePosition pos) to validate.

The ParsePosition you pass is an "in-out" parameter, you can get info out of it after you call the parse() method:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
// If you set lenient to false, ranges will be checked, e.g.
// seconds must be in the range of 0..59 inclusive.
format.setLenient(false);

String timestamp = "2014-09-11T03:27:54";
ParsePosition pos = new ParsePosition(0);

format.parse(timestamp, pos); // No declared exception, no need try-catch

if (pos.getErrorIndex() >= 0) {
    System.out.println("Input timestamp is invalid!");
} else if (pos.getIndex() != timestamp.length()) {
    System.out.println("Date parsed but not all input characters used!"
         + " Decide if it's good or bad for you!");
} else {
    System.out.println("Input is valid, parsed completely.");
}
icza
  • 389,944
  • 63
  • 907
  • 827
  • Thanks for the answer but still im struggling with validating '2014-09-11T03:27:54kanmsd' . – Amila Iddamalgoda Sep 17 '14 at 09:17
  • My solution will find that `pos.getIndex() != timestamp.length()`, you can treat that as an error if you want to. – icza Sep 17 '14 at 09:18
  • but it skips pos.getIndex() != timestamp.length() for this validation (2014-09-11T03:27:54kanmsd) ..other one (2014-09-11T03:27:54234243) is validated and ok. – Amila Iddamalgoda Sep 17 '14 at 09:35
  • For `2014-09-11T03:27:54kanmsd` the code says "not all input chars used". The other will be "Invalid" if you set `format.setLenient(false)`. I edited the code a few times, I think you use an older version. – icza Sep 17 '14 at 09:53
1

Using JodaTime it is very Easy.

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

//from your method
String inputDateString = "2014-09-11T03:27:54kanmsdklnasd";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
boolean isValid = isValidDateFormat(inputDateString, pattern);

private boolean isValidDateFormat(String inputDateString, String format){
    try {
        DateTimeFormatter dtf = DateTimeFormat.forPattern(format);
        dtf.parseDateTime(inputDateString);
    } catch (Exception ex) {
        return false;
    }
    return true;
}

You will get..
 *Exception in thread "main" java.lang.IllegalArgumentException: 
 Invalid format: "2014-09-11T03:27:54kanmsdklnasd" is malformed at "kanmsdklnasd"*
Manjunath
  • 141
  • 2
  • 7
1

java.time

The legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.

Also, check the following notice at the Home Page of Joda-Time

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

Demo using modern date-time API:

import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.stream.Stream;

public class Main {
    public static void main(String args[]) {
        Stream.of(
                "2014-09-11T03:27:54",
                "2014-09-11T03:27:54kanmsdklnasd",
                "2014-09-11T03:27:54234243"
        ).forEach(s -> {
            try {
                System.out.println(LocalDateTime.parse(s));
            }catch(DateTimeParseException e) {
                System.out.printf("The date-time string, \"%s\" is not valid.%n", s);
            }
        });;
    }
}

Output:

2014-09-11T03:27:54
The date-time string, "2014-09-11T03:27:54kanmsdklnasd" is not valid.
The date-time string, "2014-09-11T03:27:54234243" is not valid.

Learn more about the the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110