2

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

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

所以我们这样做了——值在从查询字符串中提取出来后作为字符串提交到函数中:

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

return value

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

我的快速解决方法是检查潜在的“日期”中是否有多个点,如果有,请将其保留为字符串。简单的。但问题是,虽然我们的客户目前没有使用除 UTC 日期格式以外的任何其他日期格式,但当我查看 Wikipedia 并发现有多少国家使用 dd.mm.yy 之类的标准日期格式时,我感到害怕。

有没有更好的方法可以从日期中分辨出未键入的版本号?

4

2 回答 2

3

仅凭日期值是无法做到这一点的。您真正需要的是另一个值,指示DateTime查询字符串中的格式是什么。

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

你有两个选择:

  • 如果您想要一个完全开放的值,您需要一个提示,表明应该如何解释它(您将使用它来调整您的调用以将调用中的选项设置为 DateTime.TryParse),以及如果未提供提示,那么当输入不明确时,结果可能无法确定

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

在处理用户输入时,第一个更可取,因为您希望让用户尽可能轻松并降低进入门槛。

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

在处理从 API 进行的调用时,第二个更可取,因为可以修改 DateTime 实例(或它们的表示)以符合您的期望(因为它们在调用您的 API 之前已经在内存中具有强类型表示)。

于 2012-11-14T13:12:46.313 回答
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);
      } 
   }
}

来源

于 2012-11-14T13:12:15.477 回答