Date validations in java

JSR 303 Validation for Dates

A common case is to validate date inputs in Java e.g. to avoid the nice and friendly typos like 06/01/1500.

Nevertheless by default where is not to much support to handle this very common case. So let’s fix this together:

Annotation first

The first we need is a JSR annotation which we use to annotate the code. We provide from the start proper default values, to avoid none sense data.

import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Documented // Note: We use here already a validator which we will add in a sec too @Constraint(validatedBy = InDateRangeValidator.class) @Target() @Retention(RetentionPolicy.RUNTIME) public @interface InDateRange < // used to get later in the resource bundle the i18n text String message() default ""; Class[] groups() default <>; Class[] payload() default <>; // min value, we for now just a string String min() default "1900-01-01"; // max date value we support String max() default "2999-12-31"; >

Validator next

As we have the annotation now, we still need to add some code behind for the JSR bean validation to make it really do something. I assume that both classes are in the same package.

import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class InDateRangeValidator implements ConstraintValidator  < private final SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd"); private InDateRange constraintAnnotation; @Override public void initialize(InDateRange constraintAnnotation) < this.constraintAnnotation = constraintAnnotation; >@Override public boolean isValid(java.util.Date value, ConstraintValidatorContext context) < try < final Date min = dateParser.parse(constraintAnnotation.min()); final Date max = dateParser.parse(constraintAnnotation.max()); return value == null || (value.after(min) && value.before(max)); >catch (ParseException ex) < throw new RuntimeException(ex); >> >

The validator is not very smart now, but it will do the job for. Let’s use it first, will we?

Note: This tutorial is a bit old, use nowadays the DateTimeFormatter from the Java time.

Apply our date validation

Well not to surprising but the interesting part is of course always the test case we should add to verify all is good and working as we like it.

import java.util.Date; import java.util.Set; import org.junit.Test; import static org.junit.Assert.*; import org.junit.BeforeClass; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.joda.time.LocalDate; public class TestInDateRange < private static Validator validator; @BeforeClass public static void setUp() < ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); >@Test public void testDateRange() < SomeBean test = new SomeBean(); test.date = new LocalDate(10001, 01, 01).toDate(); Set> validate = validator.validate(test); System.out.println(validate); assertEquals(1, validate.size()); assertEquals("date", validate.iterator().next().getPropertyPath().toString()); > >

i18n File

Assuming you use a default maven project we should add in /src/main/resources the file ValidationMessages.properties if it not already exists:

validation.date.InDateRange.message=date must be between and .

Note: You can use placeholders in the messages string. Here we use min and max , which automatically add the values from our annotation into the user message.

Going further

  • Well as you noticed right now we parse the min and max date each time. We could of course just do this once as it is quite static
  • We use currently java.util.Date well again something we could change
  • Last but not least we should try to avoid Date in the API / Model objects and try to just use simply UTC Long s

This entry was posted in Java, JSR Validation and tagged Java, JSR, JSR 303, Validation.
Bookmark the permalink.

6 people found this article useful This article was helpful

6 people found this article useful

Источник

Date validation in java

This purpose of this post is to provide step-by-step guidance to develop a utility that will have the following functionality:

1) This utility will help to validate a date format entered by the user.
2) If the user entered data is valid then it will be convertible to a format that can be easily inserted into the database.

Since date can be entered by the user in any format, it becomes difficult to validate it and the format might not be acceptable to be inserted into the database as well. Thus, we need to validate whether the user entered data is in a valid format or not and then we need to convert that into a format that can be easily inserted into the database.

Developing the utility:

Need to import the following packages first:
import java.sql.Date;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

The following java class will provide the required functionality:

[code language=”java”]
public class DateFormatter

public String setDisplayEffectiveDate(String date) ArrayList validDateList = new ArrayList();
validDateList.add(«dd-MMM-yyyy»);
validDateList.add(«dd.MM.yyyy»);
validDateList.add(«dd/MM/yyyy»);
validDateList.add(«MM/dd/yyyy»);
Date effectiveDate = null;
System.out.println(«setDisplayEffectiveDate1 :: date = » + date);
if (date != null) boolean correctFormat = false;
int i = 0;
String dateFormat = null;
// Parse the previous string back into a Date.
ParsePosition pos = new ParsePosition(0);
System.out.println («setDisplayEffectiveDate2 :: date = » + date);
while (!correctFormat)
if (i > validDateList.size() – 1)
break;
>
//for (int j=0;j // dateFormat = validDateList.get(i++).toString().trim();
System.out.println(«setDisplayEffectiveDate3 :: dateFormat = «+ dateFormat);
try
SimpleDateFormat fmt =
new SimpleDateFormat(dateFormat);
fmt.setLenient(false);
effectiveDate = new Date(fmt.parse(date,pos).getTime());
//log.debug(«setDisplayEffectiveDate2 :: dateFormat = «+ dateFormat);
//log.debug(«setDisplayEffectiveDate2 :: effectiveDate = «+ effectiveDate);
correctFormat = true;
>
catch (Exception e)
//log.debug(«setDisplayEffectiveDate3 :: dateFormat = «+ dateFormat);
correctFormat = false;
>
//>
>
System.out.println(«setDisplayEffectiveDate :: correctFormat = » + correctFormat);
System.out.println(«setDisplayEffectiveDate2 :: effectiveDate = «+ effectiveDate);
if (!correctFormat) //effectiveDate = new Date();
System.out.println(«setDisplayEffectiveDate :: effectiveDate (error) = «+ effectiveDate);
>

java.sql.Date sDate = new java.sql.Date(effectiveDate.getTime());
SimpleDateFormat fmt1 = new SimpleDateFormat(«dd-MMM-yyyy»);
return fmt1.format(sDate);
>

  • We define a java class – ‘DateFormatter.java’ that will hold the logic to validate a date entered by the user.
  • Inside the class we define the method – ‘setDisplayEffectiveDate(String date)’ with a parameter that will take the date entered by the user as a string.
  • We define an array list ‘validDateList’ that will hold all the possible date formats with which the user entered date will be validated against with. For e.g. In the above case, we are taking 4 formats only i.e. dd-MMM-yyyy, dd.MM.yyyy, dd/MM/yyyy, MM/dd/yyyy. The user entered date should belong to any one of these formats. However, if we need that more date formats are also allowed then we can keep adding them to the array list and the user entered date will be validated against that.
  • Then we check if the user entered date is not null or not.
[code language=”java”]
if (date != null) ….
boolean correctFormat = false; // Setting the boolean value false initially
ParsePosition pos = new ParsePosition(0);
….
>[/code]

The ParsePosition is a simple class used by Format and its subclasses to keep track of the current position during parsing. The parseObject method in the various Format classes requires a ParsePosition object as an argument.

  • We go for a while loop which loops in until the user entered date matches any of the date format defined in the array list. Once it matches it quits the loop.

Inside the while loop we do the following:

[code language=”java”]
while (!correctFormat) ….
dateFormat = validDateList.get(i++).toString().trim(); // Gets the first date format from the array list
….
try // The date format obtained above is set into the constructor of Simple Date Format class
SimpleDateFormat fmt = new SimpleDateFormat(dateFormat);
fmt.setLenient(false);
// Find the effective date/time using the constructor of the Date class
effectiveDate = new Date(fmt.parse(date,pos).getTime());
// Setting the boolean value as ‘true’ if the effective date is obtained and quit the while loop.
correctFormat = true;
> catch (Exception e) correctFormat = false;
// Else set the boolean value as false and continue with the while loop.
>
>[/code]
  • SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. It allows for formatting (date -> text), parsing (text -> date), and normalization. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting.
  • SimpleDateFormat.setLenient() method sets a value that determines whether parsing is set to lenient for this DateFormat object. Leniency is determined by the ‘Calendar’ object associated with this instance. Calendar class contains methods and members to perform basic operations involving days, weeks, months, and years.
  • The class ‘Date’ represents a specific instant in time, with millisecond precision.
  • SimpleDateFormat.parse(String source, ParsePosition pos) method will parse a date/time string according to the given parse position.
  • getTime() method provides you the total count of millisecond that have passed since 1st January 1970
  • Once the Effective Date is obtained then it is formatted into a date format that can be easily inserted into the database.
[code language=”java”]
java.sql.Date sDate = new java.sql.Date(effectiveDate.getTime());
SimpleDateFormat fmt1 = new SimpleDateFormat(«dd-MMM-yyyy»);
[/code]
  • In case the user-entered date does not match any of the formats defined then it will throw an exception which will be handled in the catch block.
[code language=”java”]
public class Start
public static void main(String[] args) try // Part-2 for Date Formatter
Start start = new Start();
DateFormatter dateformat = new DateFormatter(); // The class defined above
String data = «26/11/1952»; // User – entered date. Given as an example here.
// Calling the method of the Date Formatter class
data = start.isNull(dateformat.setDisplayEffectiveDate(data));
System.out.println(«Valid Date data after formatting – «+data);
>catch(Exception e)
System.out.println(«Exception in main method-Start() :»+e);
System.out.println(«Please enter a valid date :»);
>
>
private String isNull(String string)
// Converts null value to a blank string
if (string==null || «».equals(string.trim()) )
return » «;
>
return string.trim();
>
>[/code]

setDisplayEffectiveDate1 :: date = 26/11/1952
setDisplayEffectiveDate2 :: date = 26/11/1952
setDisplayEffectiveDate3 :: dateFormat = dd-MMM-yyyy
setDisplayEffectiveDate3 :: dateFormat = dd.MM.yyyy
setDisplayEffectiveDate3 :: dateFormat = dd/MM/yyyy
setDisplayEffectiveDate :: correctFormat = true
setDisplayEffectiveDate2 :: effectiveDate = 1952-11-26
Valid Date data after formatting – 26-Nov-1952

About the Author

I have 15 years of experience in the IT industry, working with renowned multinational corporations. Additionally, I have dedicated over a decade to teaching, allowing me to refine my skills in delivering information in a simple and easily understandable manner.

Источник

Java — how to check if String is valid date?

Geo-Baby

1. Overview

In this post we can find code which can validate if String contains valid Date based on defined pattern.

2. With SimpleDateFormat

import java.text.ParseException; import java.text.SimpleDateFormat; public class Example1 < public static void main(String[] args) < System.out.println(checkIfDateIsValid("2019-10-13")); // true System.out.println(checkIfDateIsValid("2019:10:13")); // false >private static boolean checkIfDateIsValid(String date) < SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); // With lenient parsing, the parser may use heuristics to interpret // inputs that do not precisely match this object's format. format.setLenient(false); try < format.parse(date); >catch (ParseException e) < return false; >return true; > >

3. With SimpleDateFormat + different patterns

import java.text.ParseException; import java.text.SimpleDateFormat; public class Example2 < public static void main(String[] args) < System.out.println("# Example 1"); System.out.println(checkIfDateIsValid("yyyy-MM-dd", "2019-10-13")); // true System.out.println(checkIfDateIsValid("yyyy-MM-dd", "2019:10:13")); // false System.out.println("# Example 2"); System.out.println(checkIfDateIsValid("yyyy/MM/dd", "2019/10/13")); // true System.out.println("# Example 3"); System.out.println(checkIfDateIsValid("yyyy:MM:dd", "2019:10:13")); // true System.out.println("# Example 4"); System.out.println(checkIfDateIsValid("MM/dd/yyyy", "10/13/2019")); // true >private static boolean checkIfDateIsValid(String pattern, String date) < SimpleDateFormat format = new SimpleDateFormat(pattern); // With lenient parsing, the parser may use heuristics to interpret // inputs that do not precisely match this object's format. format.setLenient(false); try < format.parse(date); >catch (ParseException e) < return false; >return true; > >
# Example 1 true false # Example 2 true # Example 3 true # Example 4 true

4. LocalDate — Java 8

import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; public class Example3 < public static void main(String[] args) < System.out.println(checkIfDateIsValid("2019-10-13")); // true System.out.println(checkIfDateIsValid("2019:10:13")); // false >private static boolean checkIfDateIsValid(String date) < try < LocalDate.parse(date, DateTimeFormatter.ISO_DATE); >catch (DateTimeParseException e) < return false; >return true; > >

5. LocalDate + DateTimeFormatter build-in patterns

import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; public class Example4 < public static void main(String[] args) < System.out.println("# Example 1"); System.out.println(checkIfDateIsValid( DateTimeFormatter.ISO_DATE, "2019-10-13")); // true System.out.println(checkIfDateIsValid( DateTimeFormatter.ISO_DATE, "2019:10:13")); // false System.out.println("# Example 2"); System.out.println(checkIfDateIsValid( DateTimeFormatter.BASIC_ISO_DATE, "20191013")); // true System.out.println("# Example 3"); System.out.println(checkIfDateIsValid( DateTimeFormatter.ISO_LOCAL_DATE, "2019-10-13")); // true >private static boolean checkIfDateIsValid(DateTimeFormatter formatter, String date) < try < LocalDate.parse(date, formatter); >catch (DateTimeParseException e) < return false; >return true; > >
# Example 1 true false # Example 2 true # Example 3 true

6. LocalDate + DateTimeFormatter different patterns

import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; public class Example5 < public static void main(String[] args) < System.out.println("# Example 1"); System.out.println(checkIfDateIsValid("yyyy-MM-dd", "2019-10-13")); // true System.out.println(checkIfDateIsValid("yyyy-MM-dd", "2019:10:13")); // false System.out.println("# Example 2"); System.out.println(checkIfDateIsValid("yyyy/MM/dd", "2019/10/13")); // true System.out.println("# Example 3"); System.out.println(checkIfDateIsValid("yyyy:MM:dd", "2019:10:13")); // true System.out.println("# Example 4"); System.out.println(checkIfDateIsValid("MM/dd/yyyy", "10/13/2019")); // true >private static boolean checkIfDateIsValid(String pattern, String date) < try < DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); LocalDate.parse(date, formatter); >catch (DateTimeParseException e) < return false; >return true; > >
# Example 1 true false # Example 2 true # Example 3 true # Example 4 true

References

Источник

Читайте также:  Discord crash bot python
Оцените статью