【问题标题】:Check if a string is a valid date using DateTime.TryParse使用 DateTime.TryParse 检查字符串是否为有效日期
【发布时间】:2013-04-18 05:30:55
【问题描述】:

我正在使用DateTime.TryParse() 函数来检查特定字符串是否是有效的日期时间,而不取决于任何文化。
令我惊讶的是,该函数返回 true 甚至字符串,如“1-1”、“1/1”等。

我该如何解决这个问题?

更新:

这是否意味着,如果我想检查一个特定的字符串是否是有效的日期时间,我需要大量的格式?我相信会有不同的组合。
根据文化,即使有很多日期分隔符('.'、'/'、'-' 等),我也很难定义要检查的格式数组。
基本上,我想检查一个特定的字符串是否至少包含天(1 到 31 或 01 到 31)、月份(1 到 12 或 01 到 12)和年份(yyyy 或 yy),以任何顺序,任何日期分隔符,解决方案是什么?
因此,如果该值包含时间的任何部分,它也应该返回 true。 我无法定义格式数组。

【问题讨论】:

  • 您首先要定义解决方案。我可以看到这两个都被解释为当年的 1 月 1 日。问题解决了。
  • 没错,伍德。我不确定这是如何工作的,但是像 "1-1000" 这样的字符串会给你 1000 年 1 月 1 日。
  • 有什么问题?按照设计,没有年份的日期默认返回今年...您需要做什么?
  • @Laurence,这个函数如何假设输入字符串的哪一部分是年份呢??
  • 我不知道它在内部是如何工作的,但是可以合理地假设如果有两个数字,并且都小于 31,那么一个是月份,一个是天。然后它会给出今年是今年。就像我告诉你“我是在 2 月 10 日做的”一样,你会认为我说的是今年……你想做什么?使用 TryParseExact() 可能会满足您的需求...

标签: c# .net


【解决方案1】:

所以这个问题已经得到回答,但对我来说,使用的代码不够简单或完整。对我来说,这就是我一直在寻找的东西,可能其他人也会喜欢它。

string dateString = "198101";

if (DateTime.TryParse(dateString, out DateTime Temp) == true)
{
     //do stuff
}

输出存储在Temp中,之后不需要,datestring是要测试的输入字符串。

【讨论】:

  • 这更多是我想要的,但我无法让这条线正常工作 - 它不喜欢“out DateTime Temp”位。这适用于 4.5.2 框架或更高版本吗?
  • 我目前使用的是 .NET Core 1.6,上面的代码有效。
  • @Deathstalker:请看看我的建议。我和你有同样的问题 - 接受的答案是为了我的目的而详细说明的方式,但你的答案缺少一些解释。
【解决方案2】:
[TestCase("11/08/1995", Result= true)]
[TestCase("1-1", Result = false)]
[TestCase("1/1", Result = false)]
public bool IsValidDateTimeTest(string dateTime)
{
    string[] formats = { "MM/dd/yyyy" };
    DateTime parsedDateTime;
    return DateTime.TryParseExact(dateTime, formats, new CultureInfo("en-US"),
                                   DateTimeStyles.None, out parsedDateTime);
}

只需在名为 formats 的数组中指定您希望接受的日期时间格式。

【讨论】:

    【解决方案3】:

    如果您希望日期符合特定格式,请使用DateTime.TryParseExact,否则这是DateTime.TryParse 的默认行为

    DateTime.TryParse

    如果可能,此方法会尝试忽略无法识别的数据,并且 用当前填写缺少的月、日、年信息 日期。如果 s 仅包含日期而没有时间,则此方法假定 时间是午夜 12:00。如果 s 包含一个带有 a 的日期组件 两位数的年份,它转换为当前文化中的年份 当前日历基于 Calendar.TwoDigitYearMax 的值 财产。 s 中的任何前导、内部或尾随空白字符 被忽略。

    如果您想确认多种格式,请查看DateTime.TryParseExact Method (String, String[], IFormatProvider, DateTimeStyles, DateTime) 重载。来自同一链接的示例:

    string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                       "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                       "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                       "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                       "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
    string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM", 
                            "5/1/2009 6:32:00", "05/01/2009 06:32", 
                            "05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"}; 
    DateTime dateValue;
    
    foreach (string dateString in dateStrings)
    {
       if (DateTime.TryParseExact(dateString, formats, 
                                  new CultureInfo("en-US"), 
                                  DateTimeStyles.None, 
                                  out dateValue))
          Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
       else
          Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
    }
    // The example displays the following output: 
    //       Converted '5/1/2009 6:32 PM' to 5/1/2009 6:32:00 PM. 
    //       Converted '05/01/2009 6:32:05 PM' to 5/1/2009 6:32:05 PM. 
    //       Converted '5/1/2009 6:32:00' to 5/1/2009 6:32:00 AM. 
    //       Converted '05/01/2009 06:32' to 5/1/2009 6:32:00 AM. 
    //       Converted '05/01/2009 06:32:00 PM' to 5/1/2009 6:32:00 PM. 
    //       Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM.
    

    【讨论】:

    • @Kai,对于您的更新,这将是困难的(我并不是说不可能),但是您必须为您的字符串制定某种规则,REGEX 来了作为一种可能的解决方案,但我认为即使这样也不适用于所有类型的字符串。
    • 谢谢,哈比卜。大概吧。如果没有人提出解决方案,我会接受这个作为答案。
    【解决方案4】:

    另一种方法是创建一个方法来验证文本是否为日期类型。

    public bool IsDateTime(string date)
    {
        if (string.IsNullOrEmpty(date)) return false;
        return DateTime.TryParse(date, out DateTime dateTime);
    }
    

    【讨论】:

      【解决方案5】:

      如果您想匹配特定的日期格式,请使用 DateTime.TryParseExact()

       string format = "ddd dd MMM h:mm tt yyyy";
      DateTime dateTime;
      if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture,
          DateTimeStyles.None, out dateTime))
      {
          Console.WriteLine(dateTime);
      }
      else
      {
          Console.WriteLine("Not a date");
      }
      

      【讨论】:

        【解决方案6】:

        基本上,我想检查一个特定的字符串是否至少包含天(1 到 31 或 01 到 31)、月份(1 到 12 或 01 到 12)和年份(yyyy 或 yy),任何顺序日期分隔符,解决方案是什么? 因此,如果该值包含时间的任何部分,它也应该返回 true。我无法定义格式数组。

        当我遇到类似情况时,我是这样做的:

        1. 收集我的系统应该支持的所有格式。
        2. 查看了哪些是常见的或可以概括的。
        3. 学会了创建正则表达式(最初是时间的投资,但一旦你自己创建一两个就会得到回报)。也不要尝试一次性为所有格式构建 REGEX,遵循增量过程。
        4. 我创建了 REGEX 以涵盖尽可能多的格式。
        5. 对于少数情况,为了不使 REGEX 变得更加复杂,我通过 DateTime.Parse() 方法对其进行了介绍。
        6. 结合 Parse 和 REGEX,我能够验证输入是否正确/符合预期。

        这个http://www.codeproject.com/Articles/13255/Validation-with-Regular-Expressions-Made-Simple 对于理解和验证每种格式的语法都非常有帮助。

        如果有帮助,我的 2 美分......

        【讨论】:

          【解决方案7】:

          尝试使用

          DateTime.ParseExact(
              txtPaymentSummaryBeginDate.Text.Trim(),
              "MM/dd/yyyy", 
              System.Globalization.CultureInfo.InvariantCulture
          );
          

          如果输入的字符串格式不正确,它会抛出异常,所以在catch部分你可以return false;

          【讨论】:

            猜你喜欢
            • 2018-06-15
            • 2011-02-26
            • 1970-01-01
            • 1970-01-01
            • 2020-06-23
            • 2011-11-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多