4
\$\begingroup\$

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?

\$\endgroup\$
0
4
\$\begingroup\$

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).

\$\endgroup\$
4
\$\begingroup\$

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 using DateTime.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.

\$\endgroup\$
2
\$\begingroup\$

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);
\$\endgroup\$
2
  • \$\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
    Sep 8 '14 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
    Sep 8 '14 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.