I have two inputs (TextBox) on my front end.
The following code parses them from their string representation to aDateTime
object. If it fails, it then sets default values.
DateTime dateFrom;
DateTime dateTo;
if (!DateTime.TryParse(txtDateFrom.Text, out dateFrom)) { dateFrom = DateTime.Today.AddDays(-7); }
if (!DateTime.TryParse(txtDateTo.Text, out dateTo)) { dateTo = DateTime.Now; }
However, the code looks bulky. Is there a better way to write it?
3 Answers 3
If you're doing this a lot, you could consider a custom method for it:
public static DateTime TryParse(object from, Func<DateTime> failureResult)
{
DateTime result;
if (!DateTime.TryParse(from, out result))
{
result = failureResult();
}
return result;
}
Or (for when you're not accessing time-sensitive DateTime
values (i.e. not DateTime.Now()
):
public static DateTime TryParse(object from, DateTime failureResult)
{
DateTime result;
if (!DateTime.TryParse(from, out result))
{
result = failureResult;
}
return result;
}
This calls the failureResult
delegate that will return your DateTime
if DateTime's TryParse fails.
Your usage would be:
DateTime dateFrom = TryParse(txtDateFrom.Text, ()=>DateTime.Today.AddDays(-7));
DateTime dateTo = TryParse(txtDateTo.Text, ()=> DateTime.Now);
Or with the second snippet:
DateTime dateFrom = TryParse(txtDateFrom.Text, DateTime.Today.AddDays(-7));
DateTime dateTo = TryParse(txtDateTo.Text, DateTime.Now);
Sadly you cannot make a static extension method so this will have to exist somewhere else (although you could make it an extension of string).
You won't be able to change the bulkiness much but there are a few things you can do:
- indent your code. It will take more space but it will also be more readable:
DateTime dateFrom;
DateTime dateTo;
if (!DateTime.TryParse(txtDateFrom.Text, out dateFrom))
{
dateFrom = DateTime.Today.AddDays(-7);
}
if (!DateTime.TryParse(txtDateTo.Text, out dateTo))
{
dateTo = DateTime.Now;
}
- Wait for C# 6 which has inline-out-variables. This will make it possible to write the
TryParse
like this:
if (!DateTime.TryParse(txtDateFrom.Text, out DateTime dateFrom))
or even
if (!DateTime.TryParse(txtDateFrom.Text, out var dateFrom))
Use
DateTime.UtcNow
. By usingDateTime.Now
you're dependent on the location of your server which might be a problem some time in the future when you host it elsewhere.Consider making a datetime picker available in the frontend instead of a textbox. It's a lot more user-friendly and it will avoid invalid dates.
I like Nick Udell's concept, but I prefer using extension methods in this case and avoiding using negative cases - I find these more confusing at 2 AM, when something is broken, than using the positive case.
public static DateTime TryParse(this DateTime defaultValue, string TextToParse)
{
DateTime.TryParse(TextToParse, out defaultValue);
return defaultValue;
}
Usage:
DateTime dateFrom = DateTime.Today.AddDays(-7).TryParse(txtDateFrom.Text);
DateTime dateTo = DateTime.Now.TryParse(txtDateTo.Text);
-
\$\begingroup\$ Could simply be preference but
DateTime.Today.AddDays(-7).TryParse(txtDateFrom.Text);
would make me think I'm trying to get last week to do the parsing of the text, for some reason. \$\endgroup\$Nick Udell– Nick Udell2014年09月08日 14:29:15 +00:00Commented Sep 8, 2014 at 14:29 -
\$\begingroup\$ @NickUdell, I see what you mean. I would probably switch the method name to something like "TryReplaceWith" to give better clarity. \$\endgroup\$AWinkle– AWinkle2014年09月08日 14:40:40 +00:00Commented Sep 8, 2014 at 14:40