Date Validation in Android
Solution 1:
private Pattern pattern;
private Matcher matcher;
private static final String DATE_PATTERN =
"(0?[1-9]|1[012]) [/.-] (0?[1-9]|[12][0-9]|3[01]) [/.-] ((19|20)\\d\\d)";
/**
* Validate date format with regular expression
* @param date date address for validation
* @return true valid date format, false invalid date format
*/
public boolean validate(final String date){
matcher = pattern.matcher(date);
if(matcher.matches()){
matcher.reset();
if(matcher.find()){
String day = matcher.group(1);
String month = matcher.group(2);
int year = Integer.parseInt(matcher.group(3));
if (day.equals("31") &&
(month.equals("4") || month .equals("6") || month.equals("9") ||
month.equals("11") || month.equals("04") || month .equals("06") ||
month.equals("09"))) {
return false; // only 1,3,5,7,8,10,12 has 31 days
}
else if (month.equals("2") || month.equals("02")) {
//leap year
if(year % 4==0){
if(day.equals("30") || day.equals("31")){
return false;
}
else{
return true;
}
}
else{
if(day.equals("29")||day.equals("30")||day.equals("31")){
return false;
}
else{
return true;
}
}
}
else{
return true;
}
}
else{
return false;
}
}
else{
return false;
}
}
and put these codes on your onClick():
matcher = Pattern.compile(DATE_PATTERN).matcher(Birthday);
//Birthday validator
else if (!matcher.matches()) {
Toast.makeText(getApplicationContext(), "Invalid Birthday!", Toast.LENGTH_SHORt).show();
}
Solution 2:
DatePicker is quite painful to input birthday. Here is my solution:
Utils
public static final SimpleDateFormat BIRTHDAY_FORMAT_PARSER = new SimpleDateFormat("yyyy-MM-dd");
public static final String DASH_STRING = "-";
public static Calendar parseDateString(String date) {
Calendar calendar = Calendar.getInstance();
BIRTHDAY_FORMAT_PARSER.setLenient(false);
try {
calendar.setTime(BIRTHDAY_FORMAT_PARSER.parse(date));
} catch (ParseException e) {}
return calendar;
}
public static boolean isValidBirthday(String birthday) {
Calendar calendar = parseDateString(birthday);
int year = calendar.get(Calendar.YEAR);
int thisYear = Calendar.getInstance().get(Calendar.YEAR);
return year >= 1900 && year < thisYear;
}
Main Activity
private void setupBirthdayEditText() {
mBirthdayEditText.addTextChangedListener(new TextWatcher() {
int beforeTextChangedLength;
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
beforeTextChangedLength = charSequence.length();
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (!TextUtils.isEmpty(mBirthdayTextInputLayout.getError())) {
mBirthdayTextInputLayout.setError(null);
mBirthdayTextInputLayout.setErrorEnabled(false);
}
}
@Override
public void afterTextChanged(Editable editable) {
int length = editable.length();
// text is being removed
if (beforeTextChangedLength > length) return;
String str = editable.toString();
String[] strArr = str.split(Utils.DASH_STRING);
// only add dash after input year with zero dash and input month with one dash
if ((length == YEAR_LENGTH && strArr.length == 1) || (length == YEAR_MONTH_LENGTH && strArr.length == 2)) {
mBirthdayEditText.setText(str + Utils.DASH_STRING);
mBirthdayEditText.setSelection(mBirthdayEditText.length());
}
}
});
}
protected boolean isAllFieldsValid() {
String birthday = mBirthdayEditText.getText().toString().trim();
if (!Utils.isValidBirthday(birthday)) {
mBirthdayTextInputLayout.setError(getString(R.string.error_birth_date));
return false;
}
return true;
}
activity_main.xml
<android.support.design.widget.TextInputLayout
android:id="@+id/register_birthday_textinput_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorTextAppearance="@style/ErrorTextInputLayout"
>
<android.support.design.widget.TextInputEditText
android:id="@+id/register_birthday_edittext"
android:hint="@string/birth_date"
android:backgroundTint="@color/white_12"
android:inputType="date"
style="@style/BaseEditText"
android:digits="1234567890"
android:maxLength="10"
/>
</android.support.design.widget.TextInputLayout>
This is not perfect as we shouldn't check validation with try catch and user have to look to the date format during typing, but it is simple and convenient if you want to avoid default date picker.
Solution 3:
A better way would be to just show a DatePicker, which by default always provides a valid date.
Solution 4:
Date Validation(Check Format Of Date)
public Boolean checkDateFormat(String date){
if (date == null || !date.matches("^(1[0-9]|0[1-9]|3[0-1]|2[1-9])/(0[1-9]|1[0-2])/[0-9]{4}$"))
return false;
SimpleDateFormat format=new SimpleDateFormat("dd/MM/yyyy");
try {
format.parse(date);
return true;
}catch (ParseException e){
return false;
}
}