【问题标题】:TryParse datetime from invidivual time elementsTryParse 来自各个时间元素的日期时间
【发布时间】:2011-09-29 07:29:19
【问题描述】:

我需要验证某些变量是否可以创建有效的日期时间,如果可以,则使其忽略它而不抛出异常。

我有以下代码

 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。

day 小于 1 或大于 > 月的天数。

小时小于 0 或大于 > 23。

分钟小于 0 或大于 > 59。

秒小于 0 或大于 > 59。

毫秒小于 0 或大于 999。

我已经看过了,似乎没有任何特定的方法可以验证这种输入。

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

【问题讨论】:

  • 将其设为字符串并使用DateTime.TryParse
  • 查看我的(更新的)答案。

标签: c# .net parsing datetime


【解决方案1】:

你可以使用这个方法:

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

【讨论】:

    【解决方案2】:

    您已经接近正确答案: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;
    }
    

    如果输入有效则返回真,否则返回假。

    【讨论】:

    • DateTime中已经有TryParse方法了,不用自己写。
    【解决方案3】:

    想出这个问题的答案让我很开心!我认为这非常简洁,因为它验证输入,返回一个您可以轻松使用的真实值,或者一个人类可读的错误消息。此外,通过一个简单的 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);
    }
    

    【讨论】:

    • 输入是从第 3 方非托管组件中检索的,因此我们无法选择如何以切碎的形式接收它
    猜你喜欢
    • 1970-01-01
    • 2019-03-08
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 2019-09-22
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多