TryParse从invival时间元素中解析日期时间

本文关键字:时间 日期 元素 invival TryParse | 更新日期: 2023-09-27 18:01:10

我需要验证某些变量是否可以创建有效的日期时间,如果是,则在不引发异常的情况下忽略它。

我有以下代码

 int y, m, d, h, mi, s, tz;
ogrFeature.GetFieldAsDateTime(field, out y, out m, out d, out h, out mi, out s, out tz);
fdr[fdrIndex++] = new DateTime(y, m, d, h, mi, s);

目前,如果(来自MSDN(,日期时间的构建将失败

年小于1或大于>9999.

月份小于1或大于>12.

天小于1或大于>月份中的天数。

小时小于0或大于>23.

分钟小于0或大于>59.

秒小于0或大于>59.

毫秒小于0或大于>超过999。

我看了一遍,似乎没有任何具体的方法来验证这种输入。

有没有一种很好的方法来验证这个输入,而不必有一大堆if,或者用一个讨厌的try/catch来包装它并捕获ArgumentOutOfRangeException?

TryParse从invival时间元素中解析日期时间

您可以使用此方法:

public static DateTime? GetFieldAsDateTime(int y, int m, int d, 
    int h, int mi, int s)
{
    DateTime result;
    var input = 
        string.Format("{0:000#}-{1:0#}-{2:0#}T{3:0#}:{4:0#}:{5:0#}", 
        y, m, d, h, mi, s);
    if (DateTime.TryParse(input, CultureInfo.InvariantCulture, 
        System.Globalization.DateTimeStyles.RoundtripKind, out result))
    {
        return result;
    }
    return null;
}

您已经接近正确答案:TryParse模式。

public static bool TryCreateDateTime(int y, int m, int d, int h, int mi, int s, 
    out DateTime dt){
  int[] normalDays={0,31,28,31,30,31,30,31,31,30,31,30,31};
  int[] leapDays  ={0,31,29,31,30,31,30,31,31,30,31,30,31};
  dt=DateTime.MinValue;
  if(y>=1 && y<=9999 &&
    m>=1 && m<=12 &&
    d>=1 && d<=(DateTime.IsLeapYear(y) ? leapDays : normalDays)[m] &&
    h>=0 && h<=23 &&
    mi>=0 && mi<=59 && s>=0 && s<=59){
    dt=new DateTime(y,m,d,h,mi,s);
    return true;
  }
  return false;
}

如果输入有效,则返回true,否则返回false。

我很开心地想出了这个答案!我认为这非常巧妙,因为它验证了输入,返回了一个可以轻松使用的真实值,或者是一条可读的错误消息。此外,通过一个简单的if语句,您可以执行代码或处理错误。自定义你认为合适的方式(即重构到一个方法中(,如果它不适合你或不符合你的需求,我可能会尝试其他方法,因为我认为这是一个有趣的问题。基本上,这里的想法是,对于每个返回true的条件,我们只需进入下一个条件,直到没有更多的条件需要检查,然后我们返回一个Boolean.TrueString,您可以使用它来进行一些检查。

int y, m, d, h, mi, s, tz;
ogrFeature.GetFieldAsDateTime(field, out y, out m, out d, out h, out mi, out s, out tz);
string error = 
      (y < 1 || y > 9999) 
    ? (m < 1 || m > 12) 
    ? (d < 1 || d > 31) 
    ? (h < 0 || h > 23) 
    ? (m < 0 || m > 59) 
    ? (s < 0 || s > 59) 
    ? (tz < 0 || tz > 999) 
    ? Boolean.TrueString // All conditions have passed validation. Return "True".
    : "Year is less than 1 or greater than > 9999."
    : "Month is less than 1 or greater than > 12."
    : "Day is less than 1 or greater than the > number of days in month."
    : "Hour is less than 0 or greater than > 23."
    : "Minute is less than 0 or greater than > 59."
    : "Second is less than 0 or greater than > 59."
    : "Millisecond is less than 0 or greater > than 999.";
if (error == bool.TrueString) {
    fdr[fdrIndex++] = new DateTime(y, m, d, h, mi, s);
}
else {
    // Display error, for example:
    // ie.
    MessageBox.Show(error, "Incorrect Date Format", MessageBoxButtons.OK, MessageBoxIcon.Error);
}