解析字符串输入 C#
Parsing string input C#
假设我有一个绑定到控制台输入的字符串,并且必须包含以下任何格式的日期数据:
"dd/mm/yyyy"
"dd.mm.yyyy"
"dd,mm,yyyy"
将此字符串解析为 DateTime
对象的最安全方法是什么?我应该使用 Regex
方法还是简单地使用上面提到的所有可能的输入格式迭代 String.Format()
方法直到它成功解析?
DateTime.ParseExact
确实有一个重载,您可以为其提供多种格式
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified array of formats,
culture-specific format information, and style. The format of the
string representation must match at least one of the specified formats
exactly or an exception is thrown.
将 CultureInfo.InvariantCulture
传递给 IFormatProvider 应该正确处理 .
,
/
的分隔符
var dateformats = new[] { "dd/mm/yyyy", "dd.mm.yyyy", "dd,mm,yyyy" };
DateTime.ParseExact("23/04/2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime.ParseExact("23.04.2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime.ParseExact("23,04,2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
您需要使用 DateTime.TryParseExact
因为有多种格式它不会产生任何异常
Converts the specified string representation of a date and time to its
DateTime equivalent. The format of the string representation must
match a specified format exactly. The method returns a value that
indicates whether the conversion succeeded.
DateTime.ParseExact
方法
Converts the specified string representation of a date and time to its
DateTime equivalent.
或
DateTime.TryParseExact
方法
Converts the specified string representation of a date and time to
its DateTime equivalent. The format of the string representation must
match a specified format exactly. The method returns a value that
indicates whether the conversion succeeded.
注:
Parse takes regional settings (culture of current thread) into
account. Therefore, you need to specify the correct format explicitly
with an invariant culture eg. en-US
我认为只需遍历 String.Format,这可能比使用正则表达式更容易。但是,如果您有实际用户输入到您获得 DateTimes 的任何地方,则正则表达式更安全,但它仍然应该被尝试使其防崩溃。
使用DateTime.ParseExact或DateTime.TryParseExact是不够的。 /
是一个特殊的格式字符,日期分隔符。在格式字符串中,它将替换为应用程序当前区域性的任何日期分隔符。它无法转义,因为它 不是 像 \
这样的特殊字符。如果您的系统文化使用 .
(俄罗斯和其他国家/地区),这将导致问题。
要指定不同的日期分隔符,您需要使用所需的分隔符创建一个 CultureInfo 对象。以下函数接受分隔符列表并尝试使用每个分隔符解析日期,直到其中一个成功:
public static bool TryParseDate(string input, string[] separators, out DateTime date)
{
var ci = (CultureInfo) CultureInfo.InvariantCulture.Clone();
foreach (var separator in separators)
{
ci.DateTimeFormat.DateSeparator = separator;
DateTime result;
if (DateTime.TryParseExact(input, "dd/MM/yyyy", ci, DateTimeStyles.None,
out date))
return true;
}
date=new DateTime();
return false;
}
无需定义多种格式,因为 dd/MM/yyyy
匹配所有大小写。
这样您就可以编写如下代码片段:
var separators = new []{"/",".",",","-"};
DateTime result;
var success1 = TryParseDate("12.05.2015", separators, out result);
var success2 = TryParseDate("12/05/2015", separators, out result);
var success3 = TryParseDate("12,05,2015", separators, out result);
var success4 = TryParseDate("12-05-2015", separators, out result);
我添加了 -
,因为我看到它在德国是一种常见的分隔符。您可以通过将格式作为另一个参数传递来使该函数更加通用。
TryParseExact
接受多个格式参数。如果不是 /
分隔符,您可以使用所有格式编写一个调用:
var formats=new []{"dd.MM.yyyy","dd,MM,yyyy","dd-MM-yyyy"};
DateTime result;
var success=DateTime.TryParseExact(input, formats,
CultureInfo.InvariantCulture, DateTimeStyles.None,
out date)
假设我有一个绑定到控制台输入的字符串,并且必须包含以下任何格式的日期数据:
"dd/mm/yyyy"
"dd.mm.yyyy"
"dd,mm,yyyy"
将此字符串解析为 DateTime
对象的最安全方法是什么?我应该使用 Regex
方法还是简单地使用上面提到的所有可能的输入格式迭代 String.Format()
方法直到它成功解析?
DateTime.ParseExact
确实有一个重载,您可以为其提供多种格式
Converts the specified string representation of a date and time to its DateTime equivalent using the specified array of formats, culture-specific format information, and style. The format of the string representation must match at least one of the specified formats exactly or an exception is thrown.
将 CultureInfo.InvariantCulture
传递给 IFormatProvider 应该正确处理 .
,
/
var dateformats = new[] { "dd/mm/yyyy", "dd.mm.yyyy", "dd,mm,yyyy" };
DateTime.ParseExact("23/04/2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime.ParseExact("23.04.2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime.ParseExact("23,04,2015", dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
您需要使用 DateTime.TryParseExact
因为有多种格式它不会产生任何异常
Converts the specified string representation of a date and time to its DateTime equivalent. The format of the string representation must match a specified format exactly. The method returns a value that indicates whether the conversion succeeded.
DateTime.ParseExact
方法
Converts the specified string representation of a date and time to its DateTime equivalent.
或
DateTime.TryParseExact
方法
Converts the specified string representation of a date and time to its DateTime equivalent. The format of the string representation must match a specified format exactly. The method returns a value that indicates whether the conversion succeeded.
注:
Parse takes regional settings (culture of current thread) into account. Therefore, you need to specify the correct format explicitly with an invariant culture eg. en-US
我认为只需遍历 String.Format,这可能比使用正则表达式更容易。但是,如果您有实际用户输入到您获得 DateTimes 的任何地方,则正则表达式更安全,但它仍然应该被尝试使其防崩溃。
使用DateTime.ParseExact或DateTime.TryParseExact是不够的。 /
是一个特殊的格式字符,日期分隔符。在格式字符串中,它将替换为应用程序当前区域性的任何日期分隔符。它无法转义,因为它 不是 像 \
这样的特殊字符。如果您的系统文化使用 .
(俄罗斯和其他国家/地区),这将导致问题。
要指定不同的日期分隔符,您需要使用所需的分隔符创建一个 CultureInfo 对象。以下函数接受分隔符列表并尝试使用每个分隔符解析日期,直到其中一个成功:
public static bool TryParseDate(string input, string[] separators, out DateTime date)
{
var ci = (CultureInfo) CultureInfo.InvariantCulture.Clone();
foreach (var separator in separators)
{
ci.DateTimeFormat.DateSeparator = separator;
DateTime result;
if (DateTime.TryParseExact(input, "dd/MM/yyyy", ci, DateTimeStyles.None,
out date))
return true;
}
date=new DateTime();
return false;
}
无需定义多种格式,因为 dd/MM/yyyy
匹配所有大小写。
这样您就可以编写如下代码片段:
var separators = new []{"/",".",",","-"};
DateTime result;
var success1 = TryParseDate("12.05.2015", separators, out result);
var success2 = TryParseDate("12/05/2015", separators, out result);
var success3 = TryParseDate("12,05,2015", separators, out result);
var success4 = TryParseDate("12-05-2015", separators, out result);
我添加了 -
,因为我看到它在德国是一种常见的分隔符。您可以通过将格式作为另一个参数传递来使该函数更加通用。
TryParseExact
接受多个格式参数。如果不是 /
分隔符,您可以使用所有格式编写一个调用:
var formats=new []{"dd.MM.yyyy","dd,MM,yyyy","dd-MM-yyyy"};
DateTime result;
var success=DateTime.TryParseExact(input, formats,
CultureInfo.InvariantCulture, DateTimeStyles.None,
out date)