区分日期/时间与版本

时间:2012-11-14 12:53:00

标签: c# .net validation date

遇到了一个奇怪的问题。前几天在我们的代码中。我想出了一个快速修复,但我不禁想知道是否有更好的方法。

当将通过QueryString提交的字符串值解析为最终在SQL存储过程中的类型化对象时,问题就出现了。对于大多数最终的比较类型,比较字符串很好,但要使用日期“小于”或“大于”等,字符串必须首先转换为日期。

所以我们这样做 - 在从查询字符串中拉出后,将值作为字符串提交到函数中:

if (DateTime.TryParse(value, out newTime))
{
    value = newTime.ToStringIsoUtc();
}

return value

多年来一直运行良好,直到有人试图提交由三部分组成的版本号。突然1.3.1成为2001-03-01,比较停止了。

我的快速解决方法是检查潜在的“日期”中是否有多个点,如果是,请将其保留为字符串。简单。但麻烦的是,虽然我们的客户目前都没有使用UTC日期格式以外的任何东西,但是当我查看维基百科并发现有多少国家使用像dd.mm.yy这样的标准日期格式时,我感到很害怕。

是否有更好的方法从日期告知无类型的版本号?

2 个答案:

答案 0 :(得分:3)

单独使用 日期值无法实现此目的。您真正需要的是另一个值,表示查询字符串中DateTime的格式是什么。

以您的1.3.1格式为例。谁能说它真的不能被解释为2011年1月3日(从左到右而不是从右到左看)。

您有两种选择:

  • 如果您想要一个完全开放的值,您需要一个提示,说明应如何解释(您将用于调整您的调用以设置调用DateTime.TryParse中的选项),以及警告如果没有提供提示,那么当输入不明确时结果可能是不确定的

  • 拒绝任何不符合预期格式的内容。

在处理用户输入时,第一个是首选,因为您希望为用户提供尽可能简单的功能并降低进入条形。

请注意,如果用户输入来自使用HTML 5的网页,您应该知道input标记允许datedatetime输入类型。这不仅具有允许浏览器提供标准化(至少在整个平台上)输入此类数据的方式的好处,而且还提供标准化数据传输的格式,这意味着您的输入更多地归入# 2比在#1中。

当处理来自API的调用时,第二个是优选的,因为可以修改DateTime实例(或它们的表示)以满足您的期望(因为它们在调用API之前已经在内存中具有强类型表示)。 / p>

答案 1 :(得分:1)

  

多年来一直运作良好,直到有人试图提交   三部分版本号。突然1.3.1成为2001-03-01而且   比较停止了工作。

这就是你应该使用 DateTime ParseExact(string s,string format,IFormatProvider povider)

的原因
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string dateString, format;  
      DateTime result;
      CultureInfo provider = CultureInfo.InvariantCulture;

      // Parse date-only value with invariant culture.
      dateString = "06/15/2008";
      format = "d";
      try {
         result = DateTime.ParseExact(dateString, format, provider);
         Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
      }
      catch (FormatException) {
         Console.WriteLine("{0} is not in the correct format.", dateString);
      } 

      // Parse date-only value without leading zero in month using "d" format.// Should throw a FormatException because standard short date pattern of  // invariant culture requires two-digit month.
      dateString = "6/15/2008";
      try {
         result = DateTime.ParseExact(dateString, format, provider);
         Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
      }
      catch (FormatException) {
         Console.WriteLine("{0} is not in the correct format.", dateString);
      }

      // Parse date and time with custom specifier.
      dateString = "Sun 15 Jun 2008 8:30 AM -06:00";
      format = "ddd dd MMM yyyy h:mm tt zzz";
      try {
         result = DateTime.ParseExact(dateString, format, provider);
         Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
      }
      catch (FormatException) {
         Console.WriteLine("{0} is not in the correct format.", dateString);
      }

      // Parse date and time with offset but without offset's minutes. // Should throw a FormatException because "zzz" specifier requires leading  // zero in hours.
      dateString = "Sun 15 Jun 2008 8:30 AM -06";
      try {
         result = DateTime.ParseExact(dateString, format, provider);
         Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
      }   
      catch (FormatException) {
         Console.WriteLine("{0} is not in the correct format.", dateString);
      } 

      dateString = "15/06/2008 08:30";
      format = "g";
      provider = new CultureInfo("fr-FR");
      try {
         result = DateTime.ParseExact(dateString, format, provider);
         Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
      }   
      catch (FormatException) {
         Console.WriteLine("{0} is not in the correct format.", dateString);
      } 
   }
}

Source