31600

I want to write a generic function where for these valid date format MM/dd/yyyy, M/dd/yyyy or M/d/yy

Question:

I have a flat file with below data

2/12/2016 2/3/2017 12/23/2017 04/23/2017

first is in M/dd/yyyy, second is in M/d/yyyy and rest of them having date format MM/dd/yyyy. I am using below function to check data validity for above data file.

public static boolean isValidDateFormat(String format, String value) { boolean Retval = false; Date date = null; SimpleDateFormat sdf = new SimpleDateFormat(format); date = sdf.parse(value); if (value.equals(sdf.format(date))) { Retval= true; } return Retval; }

I have to check date validity within loop and can pass only one date format like isValidDateFormat("MM/dd/yyyy", "2/12/2016"). Above function return false for first two values and true for rest of them.

I want to write a generic function where for these valid date format MM/dd/yyyy, M/dd/yyyy or M/d/yyyy, function return true.

Answer1:

Why not just allow to provide to method more than one format?

public static boolean isValidDateFormat(String value, String... formats) { for(String format : formats) { SimpleDateFormat sdf = new SimpleDateFormat(format); Date date = sdf.parse(value); if(value != null && value.equals(sdf.format(date)) ) { return true; } } return false; }

then you can keep your allowed formats in collection and provide it to the method

String[] formats = new String[]{"dd.mm.yyyy", "dd/mm/yyyy"}; if(isValidDateFormat("12.12.2014", formats) { //do sth }

Answer2:

Using the java.time API, your method could be rewritten to this

public static boolean isValidDateFormat(String value){ try { LocalDate.parse(value, DateTimeFormatter.ofPattern("M/d/uuuu").withResolverStyle(ResolverStyle.STRICT)); } catch (DateTimeParseException e) { return false; } return true; }

This will return true for MM/dd/yyyy, M/dd/yyyy, MM/d/yyyy, M/d/yyyy.

We need to specify the ResolveStyle explicitly here. Java uses ResolverStyle.SMART as a default. This allows you to enter days in the range of 1 - 31 for every month, and Java converts invalid days (30th of February for example) to the last valid day of the month.

We don't need that "smart" behaviour here, hence the ResolverStyle.STRICT.

<hr />

This is not as neat or short, but works as well:

public static boolean isValidDateFormat(String value){ String[] sa = value.split("/"); if (sa[2].length() != 4) return false; try { LocalDate.of(Integer.parseInt(sa[2]), Integer.parseInt(sa[0]), Integer.parseInt(sa[1])); } catch (DateTimeException e) { return false; } return true; }

Answer3:

An alternative to using a validation based on SimpleDateFormats would be using a regex which would accept the 3 different formats :

value.matches("(0?\\d|1[0-2])/([0-2]?\\d|3[01])/\\d{4}")

I expect it to be much more efficient, however it has multiple problems :

<ul><li>

it does accept some invalid dates that I think would be rejected by the SimpleDateFormat, such as 02/31/2017

</li> <li>

you should then change your method's signature since the format argument doesn't make sense anymore (unless you want to pass the regex there)

</li> <li>

it loses some meaning : regexp matches any text, while a SimpleDateFormat explicitly matches dates (represented as text)

</li> </ul>

Answer4:

The favourable solution would be to make the date entries consistent in the flat file in the first place so that you will only have to use one DateFormat. You could perhaps write a utility to prefix any single digit month or day entries with 0s.

Alternatively, you could employ a utility method to sanity check the date before selecting a DateFormat. For example, it could split the String at the '/' character, giving you an array of Strings. You could then check the length of the first two tokens of the array to determine which Date format you need to use.

Recommend

  • PySpark - RDD to JSON
  • Select lines by condition and count with one line command
  • BufferReader reading empty lines
  • How to insert text after a particular line of a file
  • Difference between optional values in swift?
  • Multiple GET parameter with Express
  • App isn't responding because of Service START_CONTINUATION_MASK
  • Eclipse new plugin Project: Not choosable
  • String contains letters
  • jQuery random blockquote
  • A simple datepicker in VueJS
  • Django: DRY principle and UserPassesTestMixin
  • Read a file in “chunks” using PHP
  • string.IsNullOrEmpty() Doesn't Seem to Work on a String within a Class within a Class
  • Leaflet z-index
  • How to open multiple instances of a program in Linux
  • auth.provider is not set to 'password' when user signs-in with email and password
  • How can I extend PHP DOMElement?
  • Where these are stored?
  • Get localized short date pattern as String?
  • Trying to string.Join an IList
  • abstracting over a collection
  • How can I tell a form not to dispose a particular control when it closes?
  • Unable to decode certificate at client new X509Certificate2()
  • Parse a date string in a specific locale (not timezone!)
  • Remove final comma from string in vb.net
  • How to do unit test for HttpContext.Current.Server.MapPath
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Apache 2.4 and php-fpm does not trigger apache http basic auth for php pages
  • Cross-Platform Protobuf Serialization
  • Does CUDA 5 support STL or THRUST inside the device code?
  • Release, debug version and Authorization Google?
  • Is there a mandatory requirement to switch app.yaml?
  • How to format a variable of double type
  • retrieve vertices with no linked edge in arangodb
  • coudnt use logback because of log4j
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • How can I remove ASP.NET Designer.cs files?
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • JaxB to read class hierarchy