我是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;
}
}
答案 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"))
}