Android中的日期验证

时间:2013-07-02 02:41:21

标签: android

我是Android编程的新手,我正在开发一款应用。有人可以帮助我验证用户输入的日期是否有效?

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{
           return false;
      }        
  }
  else{
      return false;
  }              
}

6 个答案:

答案 0 :(得分:7)

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;
  }              
}

并将这些代码放在onClick()上:

matcher = Pattern.compile(DATE_PATTERN).matcher(Birthday);

//Birthday validator
    else if (!matcher.matches()) {
    Toast.makeText(getApplicationContext(), "Invalid Birthday!", Toast.LENGTH_SHORt).show();                    
}

答案 1 :(得分:2)

更好的方法是只显示DatePicker,默认情况下始终提供有效日期。

答案 2 :(得分:2)

DatePicker输入生日非常痛苦。这是我的解决方案:

实用程序

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;
    }

主要活动

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>

这并不完美,因为我们不应该使用try catch检查验证,用户在打字时必须查看日期格式,但如果您想避免使用默认日期选择器,则简单方便。

答案 3 :(得分:1)

这也假定为DD / MM / YYYY格式,但日期是基于区域设置的,因此可以是MM / DD / YYYY,例如在美国!

答案 4 :(得分:0)

日期验证(日期检查格式)

 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;
    }
}

答案 5 :(得分:0)

我是用Kotlin用MM/dd/yyyy格式完成的。

fun validateDate(date: String): Boolean {
        val regex = "^(0[0-9]||1[0-2])/([0-2][0-9]||3[0-1])/([0-9][0-9])?[0-9][0-9]$"
        val matcher = Pattern.compile(regex).matcher(date)
        return if (matcher.matches()) {
            matcher.reset()
            if (matcher.find()) {
                val dateDetails = date.split("/")
                val day: String = dateDetails[1]
                val month: String = dateDetails[0]
                val year: String = dateDetails[2]
                if (validateMonthWithMaxDate(day, month)) {
                    false
                } else if (isFebruaryMonth(month)) {
                    if (isLeapYear(year)) {
                        leapYearWith29Date(day)
                    } else {
                        notLeapYearFebruary(day)
                    }
                } else {
                    true
                }
            } else {
                false
            }
        } else {
            false
        }
    }

    private fun validateMonthWithMaxDate(day: String, month: String): Boolean = day == "31" && (month == "4" || month == "6" || month == "9" || month == "11" || month == "04" || month == "06" || month == "09")
    private fun isFebruaryMonth(month: String): Boolean = month == "2" || month == "02"
    private fun isLeapYear(year: String): Boolean = year.toInt() % 4 == 0
    private fun leapYearWith29Date(day: String): Boolean = !(day == "30" || day == "31")
    private fun notLeapYearFebruary(day: String): Boolean = !(day == "29" || day == "30" || day == "31")

已通过单元测试用例验证。

@Test
    fun `it should validate date`() {
        Assert.assertTrue(subject.validateDate("12/01/2012"))
        Assert.assertTrue(subject.validateDate("01/12/2012"))
        Assert.assertFalse(subject.validateDate("13/12/2012"))
        Assert.assertFalse(subject.validateDate("13/01/2012"))
        Assert.assertFalse(subject.validateDate("12/32/2012"))
        Assert.assertFalse(subject.validateDate("14/01/2012"))
        Assert.assertFalse(subject.validateDate("15/43/2012"))
        Assert.assertTrue(subject.validateDate("02/28/2012"))
        Assert.assertTrue(subject.validateDate("02/29/2012"))
        Assert.assertFalse(subject.validateDate("02/29/2013"))
        Assert.assertFalse(subject.validateDate("02/29/2015"))
        Assert.assertTrue(subject.validateDate("02/29/2016"))
        Assert.assertFalse(subject.validateDate("02/30/2012"))
        Assert.assertTrue(subject.validateDate("02/29/2004"))
        Assert.assertFalse(subject.validateDate("02/31/2004"))
        Assert.assertFalse(subject.validateDate("14/30/2012"))
        Assert.assertFalse(subject.validateDate("01/32/2012"))
        Assert.assertFalse(subject.validateDate("13/03/2012"))
        Assert.assertTrue(subject.validateDate("10/12/2000"))
    }