【问题标题】:Differentiate Date/Time from Version区分日期/时间与版本
【发布时间】:2012-11-14 12:52:59
【问题描述】:

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

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

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

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

return value

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

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

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

【问题讨论】:

  • 我认为没有通用的方法可以做到这一点。想象一下有效日期,也可以是有效版本:1.12.2012 或……可以是日期,也可以是 s.b. 的版本。每次构建都会增加修订号。
  • 您希望支持哪些输入日期格式(视为有效输入)? dd/MM/yyyy、MM/dd/yyyy 等?
  • 您为什么担心不适用于您的客户的时间和日期格式?如果您使用DateTime.ParseExact,您可以忽略任何不适用于您的客户的格式。

标签: c# .net validation date


【解决方案1】:

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

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

你有两个选择:

    1234563如果没有提供提示,那么当输入不明确时,结果可能无法确定
  • 拒绝任何不符合预期格式的内容。

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

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

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

【讨论】:

  • 是的,我认为这可能就是答案。但我想看看是否有其他解决方案。感谢您证实我的怀疑。
  • @MattThrower 根据提交查询字符​​串的内容,您可能会倾向于 2),因为 HTML5 允许输入类型为 datedatetime。如果您知道您的网页是 HTML5 格式,那么每次都会保证您的值的格式,就像您在 URL 中有提供值的代码一样。
  • 遗憾的是输入不是来自表单 - 我应该说清楚。它在调用有效的 Web 服务时出现在 QueryString 上,因此我们无法在它到达我们的代码之前对其进行清理。
  • @MattThrower 如果是这种情况,那么如果输入与所需的exact 格式不匹配,您应该绝对 坚持拒绝输入;因为它是机器与机器交谈,所以很容易确保并且在没有遇到您期望的情况时应该完全停止(否则您会损害自己)。在这种情况下,使用具有特定格式的DateTime.TryParseExact 是可行的方法。其他任何事情都是失败(从长远来看,这实际上也为您的客户提供了一些安全性,因为它表明他们的流程何时失败)。
【解决方案2】:

多年来一直运行良好,直到有人尝试提交 三部分的版本号。突然 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

【讨论】:

  • 谢谢。这是我尝试的第一种方法,但它仍然(显然)将格式限制为我们认为“可接受”的格式。我想看看是否有更开放的就业机会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 2017-02-22
  • 1970-01-01
  • 2017-12-15
相关资源
最近更新 更多