C# 如何用3个整数检查日期是否有效?(返回bool的方法)

C# 如何用3个整数检查日期是否有效?(返回bool的方法),c#,methods,properties,boolean,C#,Methods,Properties,Boolean,我正在尝试制作一种方法来检查是否正确插入了日、月和年。方法在date正常时返回TRUE,在date不正常时返回FALSE问题:代码总是返回false。 const int max_year = 2100; const int min_year = 1900; static bool CheckDate(int d, int m, int y) { if (d < 1 || d > 31) { if (m < 1 || m > 12)

我正在尝试制作一种方法来检查是否正确插入了日、月和年。方法在date正常时返回TRUE,在date不正常时返回FALSE问题:代码总是返回false。

const int max_year = 2100;
const int min_year = 1900;

static bool CheckDate(int d, int m, int y)   
{
    if (d < 1 || d > 31)
    {
        if (m < 1 || m > 12)
        {
            if (y < min_year || y > max_year)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return true;
        }
    }
    else
    {
        return true;
    }
}
或者你可以这样做:

static bool CheckDate(int d, int m, int y) 
{
   try
   {
      // This will throw an exception if the year, month or day are invalid
      var temp = new DateTime(y, m, d);
      return true;
   }
   except
   {
     return false;
   }
}
或者你可以这样做:

static bool CheckDate(int d, int m, int y) 
{
   try
   {
      // This will throw an exception if the year, month or day are invalid
      var temp = new DateTime(y, m, d);
      return true;
   }
   except
   {
     return false;
   }
}

尽可能简单,只需将数字转换为字符串,然后使用yyyyMMdd格式执行DateTime.TryParseExact

bool CheckDate(int y, int m, int d)
{

    string t = $"{y:D4}{m:D2}{d:D2}";
    return DateTime.TryParseExact(t, "yyyyMMdd", CultureInfo.InvariantCulture,DateTimeStyles.None,  out DateTime dt);
}
当然,如果您想限制有效年数,可以添加一个简单的逻辑来测试y变量,就像您现在在构建要解析的字符串之前所做的那样

if (y < min_year || y > max_year)
    return false;
....
if(ymax|u year)
返回false;
....

尽可能简单,只需将数字转换为字符串,然后使用yyyyMMdd格式执行DateTime.TryParseExact

bool CheckDate(int y, int m, int d)
{

    string t = $"{y:D4}{m:D2}{d:D2}";
    return DateTime.TryParseExact(t, "yyyyMMdd", CultureInfo.InvariantCulture,DateTimeStyles.None,  out DateTime dt);
}
当然,如果您想限制有效年数,可以添加一个简单的逻辑来测试y变量,就像您现在在构建要解析的字符串之前所做的那样

if (y < min_year || y > max_year)
    return false;
....
if(ymax|u year)
返回false;
....

我想指出属性设置程序中可能存在的错误和/或糟糕的设计(这可能是“代码总是返回false”的原因)

如果仔细观察,您会发现
CheckDate
总是使用参数
dan
mesec
year
调用。如您所知,
value
是要设置的值(
Day=1
,或
Day=500
),但它不是
CheckDate
调用的一部分

如果这是你的目的,我可以说这是非常糟糕的设计。您应该直接在代码中调用
CheckDate
,而不是像属性setter那样有副作用

public int Day
{
    get
    {
        return day;
    }
    set
    {
        // Why this?
        if (CheckDate(dan, mesec, year) == true)
        {
            day = value;
        }
        else
        {
            throw new Exception("Day is incorrect!");
        }
    }
}

我想指出属性setter中可能存在的bug和/或糟糕的设计(这可能是“代码总是返回false”的原因)

如果仔细观察,您会发现
CheckDate
总是使用参数
dan
mesec
year
调用。如您所知,
value
是要设置的值(
Day=1
,或
Day=500
),但它不是
CheckDate
调用的一部分

如果这是你的目的,我可以说这是非常糟糕的设计。您应该直接在代码中调用
CheckDate
,而不是像属性setter那样有副作用

public int Day
{
    get
    {
        return day;
    }
    set
    {
        // Why this?
        if (CheckDate(dan, mesec, year) == true)
        {
            day = value;
        }
        else
        {
            throw new Exception("Day is incorrect!");
        }
    }
}

除了你的实际问题,如果我让它确认4月31日呢?有更好的方法可以做到这一点,你不需要推出自己的解决方案。适用于CheckDate(1,12019)?这只是一个简单的例子。稍后我将添加其他验证。现在我只检查白天是否在1到31之间,月份是否在1到12之间,年份是否在1900到2100之间@BrootTime已经可以做到这一点,因此无需重新实现它。您可以使用例如
static bool CheckDate(int d,int m,int y){return minu_year如果您使用
CheckDate(52000123456)
它将返回
true
,因为一旦您的d介于1和31之间,您总是返回true。
CheckDate(0,52000)也是如此
除了您的实际问题之外,如果我让it部门在4月31日进行验证会怎么样?有更好的方法可以做到这一点,您无需推出自己的解决方案。使用CheckDate(1,12019)可以很好地工作?这只是一个简单的例子。我稍后会添加其他验证。现在我只检查日期是否在1和31之间,月份是否在1和12之间,年份是否在1900和2100之间。@BrootsWaymbDateTime已经可以这样做了,所以不需要重新实现它。您可以使用例如
静态bool CheckDate(int d,int m,int y){return minu_year如果您执行
CheckDate(52000123456)
它将返回
true
,因为一旦您的d介于1和31之间,您总是返回true。对于
CheckDate(020000)
您不需要创建字符串并再次解析它的往返过程。您可以尝试创建一个
新的日期时间(y,m,d)
这将引发任何无效日期。不,这将是错误的,因为您将使用异常驱动代码。TryParse将避免代价高昂的异常。对于无效日期,这将快得多。@derpirscher TryParseExact避免引发异常,但您不希望故意引发异常。从性能角度来看,抛出异常在“正常”中避免异常的良好实践验证逻辑。编辑:3条类似的注释:)而不是返回TryParseExact的结果,而是在如下变量中捕获结果:var result=DateTime.TryParseExact…如果为false,则返回它,但如果为true,则检查日期是否在1900年1月1日到2100年12月31日之间。您不需要往返创建一个字符串并再次解析它。您可以尝试创建一个新的日期时间(y,m,d)
这将引发任何无效日期。不,这将是错误的,因为您将使用异常驱动代码。TryParse将避免代价高昂的异常。对于无效日期,这将快得多。@derpirscher TryParseExact避免引发异常,但您不希望故意引发异常。从性能角度来看,抛出异常在“正常”中避免异常的良好实践验证逻辑。编辑:3条类似的注释:)而不是返回TryParseExact的结果,而是在如下变量中捕获结果:var result=DateTime.TryParseExact…如果为false,则返回它,如果为true,则检查日期是否在1900年1月1日到2100年12月31日之间