遇到了一个奇怪的问题。前几天在我们的代码中。我想出了一个快速修复,但我不禁想知道是否有更好的方法。
当将通过QueryString提交的字符串值解析为最终在SQL存储过程中的类型化对象时,问题就出现了。对于大多数最终的比较类型,比较字符串很好,但要使用日期“小于”或“大于”等,字符串必须首先转换为日期。
所以我们这样做 - 在从查询字符串中拉出后,将值作为字符串提交到函数中:
if (DateTime.TryParse(value, out newTime))
{
value = newTime.ToStringIsoUtc();
}
return value
多年来一直运行良好,直到有人试图提交由三部分组成的版本号。突然1.3.1成为2001-03-01,比较停止了。
我的快速解决方法是检查潜在的“日期”中是否有多个点,如果是,请将其保留为字符串。简单。但麻烦的是,虽然我们的客户目前都没有使用UTC日期格式以外的任何东西,但是当我查看维基百科并发现有多少国家使用像dd.mm.yy这样的标准日期格式时,我感到很害怕。
是否有更好的方法从日期告知无类型的版本号?
答案 0 :(得分:3)
单独使用 日期值无法实现此目的。您真正需要的是另一个值,表示查询字符串中DateTime
的格式是什么。
以您的1.3.1
格式为例。谁能说它真的不能被解释为2011年1月3日(从左到右而不是从右到左看)。
您有两种选择:
如果您想要一个完全开放的值,您需要一个提示,说明应如何解释(您将用于调整您的调用以设置调用DateTime.TryParse
中的选项),以及警告如果没有提供提示,那么当输入不明确时结果可能是不确定的
拒绝任何不符合预期格式的内容。
在处理用户输入时,第一个是首选,因为您希望为用户提供尽可能简单的功能并降低进入条形。
请注意,如果用户输入来自使用HTML 5的网页,您应该知道input
标记允许date
和datetime
输入类型。这不仅具有允许浏览器提供标准化(至少在整个平台上)输入此类数据的方式的好处,而且还提供标准化数据传输的格式,这意味着您的输入更多地归入# 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);
}
}
}