日验证返回错误

时间:2014-12-17 15:18:15

标签: java validation calendar

日验证总是返回非法参数异常,并且从不将日期设置为输入,特别是在闰年中尝试输入29时。我一直试图找到错误很长一段时间,只是放弃了。谢谢你的帮助。

import java.util.Calendar;

public class DateOfBirth
{
    private int day;
    private int month;
    private int year;

    private Calendar cld = Calendar.getInstance();

    public DateOfBirth()
    {
        this(0,0,0);
    } 
    public DateOfBirth(int a,int b,int c)
    {
        setDay(c);
        setMonth(a);
        setYear(b);
    }
    public void setDay(int a)
    {
        if( getMonth()==2 && (getYear() % 4 == 0 && (getYear() % 100 != 0 || getYear() % 400 == 0))&& a == 29)
             day = a;
        else if(getMonth() == 2 && a <= 28)
            day = a;
        else if(getMonth() == 1 || getMonth() == 3 || getMonth() == 5 || getMonth() ==  7 || getMonth() ==  8 || getMonth() ==  10 || getMonth() == 12 && a < 31)
            day = a;
        else if(getMonth() == 4 || getMonth() == 6 || getMonth() == 9 || getMonth() == 11 && a < 30)
            day = a;
        else
            throw new IllegalArgumentException("Day Out Of Bounds.");
    }
    public void setMonth(int b)
    {
        if( b > 0 && b <= 12)
            month = b;
        else
            throw new IllegalArgumentException("Month Out of Bounds.");
    }
    public void setYear(int c)
    {
        if( c > (cld.get(Calendar.YEAR) - 150) && c < cld.get(Calendar.YEAR))
            year = c;
        else
            throw new IllegalArgumentException("Year Out of Bounds.");
    }
    public int getDay()
    {
        return day;
    }
    public int getMonth()
    {
        return month;
    }
    public int getYear()
    {
        return year;
    }
    @Override
    public String toString()
    {
        return String.format("Date Of Birth: %02d/%02d/%d",getDay(),getMonth(),getYear());
    }
}

2 个答案:

答案 0 :(得分:4)

在致电setDaysetMonth之前,您先致电setYear ,这意味着setDay没有&#39知道你在说什么月份和年份。如果没有这些信息,它可能无法验证当天是否正确。

您只需切换设置者调用的顺序:

setYear(b);
setMonth(a);
setDay(c);

然而:

  • 你的无参数构造函数试图设置一个无效值(day = 0,month = 0 - what?)那么有什么意义呢?
  • 你应该肯定重命名你的构造函数参数是有意义的(例如,有人想知道b代表年份吗?)
  • 能够单独设置每个属性会使这个很脆弱......例如,您可以将月份设置为1月,将当天设置为30,然后将月份设置为2月......所有这些都没有任何验证错误,请将您留在2月30。这基本上是你的构造函数当前发生的事情,但你也可以从外部做到这一点。

我建议你尽可能让你的课堂不变。然后你只需需要在构造函数中验证。考虑将其重构为:

// TODO: Think of a decent name. Not DateOfBirth because it's just representing
// a date, and not Date as that conflicts with java.util.Date.
public final class GregorianDate {
    private final int year, month day;

    public GregorianDate(int year, int month, int day) {
        validate(year, month, day);
        this.year = year;
        this.month = month;
        this.day = day;
    }

    private static void validate(int year, int month, int day) {
        // TODO: The validation
    }

    // getters, toString, hashCode, equals, and possibly implement
    // Comparable<GregorianDate> too.
}

当然,这是假设这只是一个练习 - 通常您使用已经提供给您的适当日期/时间API - 理想情况下避免使用java.util.Date/Calendar并使用Joda Time或Java 8 java.time API。

答案 1 :(得分:0)

你的逻辑存在缺陷我添加了括号来修复它

 public void setDay(int a)
     {
         if( getMonth()==2 && (getYear() % 4 == 0 && (getYear() % 100 != 0 || getYear() % 400 == 0))&& a == 29)
              day = a;
         else if(getMonth() == 2 && a <= 28)
             day = a;
         else if((getMonth() == 1 || getMonth() == 3 || getMonth() == 5 || getMonth() ==  7 || getMonth() ==  8 || getMonth() ==  10 || getMonth() == 12) && a < 31)
             day = a;
         else if((getMonth() == 4 || getMonth() == 6 || getMonth() == 9 || getMonth() == 11) && a < 30)
             day = a;
         else
             throw new IllegalArgumentException("Day Out Of Bounds.");
 }