Reputation: 2465
Let's say I have a string that is bound to console input and must contain date data in any of the following formats:
"dd/mm/yyyy"
"dd.mm.yyyy"
"dd,mm,yyyy"
What is the safest way to parse this string into DateTime
object? Should I use Regex
approach or simply iterate through String.Format()
method with all possible upper mentioned input formats till it succeeds in parsing?
Upvotes: 2
Views: 192
Reputation: 5743
DateTime.ParseExact
do have an overload that you can supply multiple format to it
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.
Pass CultureInfo.InvariantCulture
to IFormatProvider should handle the separator correctly for .
,
/
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);
Upvotes: 3
Reputation: 131581
It's not enough to use DateTime.ParseExact or DateTime.TryParseExact. The /
is a special formatting character, the date separator character. In a format string it will be replaced with whatever the date separator is for the application's current culture. It can't be escaped because it is not a special character like \
. This will cause problems if your system's culture uses .
(Russia and other countries).
To specify a different date separator you need to create a CultureInfo object with the separator you want. The following function accepts a list of separators and tries to parse dates using each separator until one of them succeeds:
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;
}
There's no need to define multiple formats because dd/MM/yyyy
matches all cases.
This allows you to write code like the following snippet:
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);
I added -
because I see it's a common separator in Germany. You can make the function even more generic by passing the format as another parameter.
TryParseExact
accepts multiple format parameters. If it weren't for the /
separator, you could write a single call with all formats:
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)
Upvotes: 1
Reputation: 6337
DateTime.ParseExact
Method
Converts the specified string representation of a date and time to its DateTime equivalent.
Or
DateTime.TryParseExact
Method
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.
Note :
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
Upvotes: 1
Reputation: 46
I reckon just iterate through String.Format, it is probably easier than using a regex. But if you have actual users inputing into wherever you got the DateTimes, a regex is safer, but it should still be surrounded by a try to make it crash-proof.
Upvotes: -1
Reputation: 15923
You need to use DateTime.TryParseExact
as there are multiple formats it wont generate any exceptions
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.
Upvotes: 2