How do I use DateTime.TryParse with a Nullable<DateTime>?

C#DatetimeNullable

C# Problem Overview


I want to use the DateTime.TryParse method to get the datetime value of a string into a Nullable. But when I try this:

DateTime? d;
bool success = DateTime.TryParse("some date text", out (DateTime)d);

the compiler tells me

> 'out' argument is not classified as a variable

Not sure what I need to do here. I've also tried:

out (DateTime)d.Value 

and that doesn't work either. Any ideas?

C# Solutions


Solution 1 - C#

As Jason says, you can create a variable of the right type and pass that. You might want to encapsulate it in your own method:

public static DateTime? TryParse(string text)
{
    DateTime date;
    if (DateTime.TryParse(text, out date))
    {
        return date;
    }
    else
    {
        return null;
    }
}

... or if you like the conditional operator:

public static DateTime? TryParse(string text)
{
    DateTime date;
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null;
}

Or in C# 7:

public static DateTime? TryParse(string text) =>
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null;

Solution 2 - C#

DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;

(There might be more elegant solutions, but why don't you simply do something as above?)

Solution 3 - C#

Here is a slightly concised edition of what Jason suggested:

DateTime? d; DateTime dt;
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null;

Solution 4 - C#

You can't because Nullable<DateTime> is a different type to DateTime. You need to write your own function to do it,

public bool TryParse(string text, out Nullable<DateTime> nDate)
{
    DateTime date;
    bool isParsed = DateTime.TryParse(text, out date);
    if (isParsed)
        nDate = new Nullable<DateTime>(date);
    else
        nDate = new Nullable<DateTime>();
    return isParsed;
}

Hope this helps :)

EDIT: Removed the (obviously) improperly tested extension method, because (as Pointed out by some bad hoor) extension methods that attempt to change the "this" parameter will not work with Value Types.

P.S. The Bad Hoor in question is an old friend :)

Solution 5 - C#

What about creating an extension method?

public static class NullableExtensions
{
    public static bool TryParse(this DateTime? dateTime, string dateString, out DateTime? result)
    {
        DateTime tempDate;
        if(! DateTime.TryParse(dateString,out tempDate))
        {
            result = null;
            return false;
        }

        result = tempDate;
        return true;
        
    }
}

Solution 6 - C#

This is the one liner you're looking for:

DateTime? d = DateTime.TryParse("some date text", out DateTime dt) ? dt : null;

If you want to make it a proper TryParse pseudo-extension method, you can do this:

public static bool TryParse(string text, out DateTime? dt)
{
    if (DateTime.TryParse(text, out DateTime date))
    {
        dt = date;
        return true;
    }
    else
    {
        dt = null;
        return false;
    }
}

Solution 7 - C#

I don't see why Microsoft didn't handle this. A smart little utility method to deal with this (I had the issue with int, but replacing int with DateTime will be the same effect, could be.....

    public static bool NullableValueTryParse(string text, out int? nInt)
    {
        int value;
        if (int.TryParse(text, out value))
        {
            nInt = value;
            return true;
        }
        else
        {
            nInt = null;
            return false;
        }
    }

Solution 8 - C#

Here's a single line solution:

DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;

Solution 9 - C#

Alternatively, if you are not concerned with the possible exception raised, you could change TryParse for Parse:

DateTime? d = DateTime.Parse("some valid text");

Although there won't be a boolean indicating success either, it could be practical in some situations where you know that the input text will always be valid.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrian SullivanView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Jason KealeyView Answer on Stackoverflow
Solution 3 - C#SonnyView Answer on Stackoverflow
Solution 4 - C#Binary WorrierView Answer on Stackoverflow
Solution 5 - C#user2687864View Answer on Stackoverflow
Solution 6 - C#cpcolellaView Answer on Stackoverflow
Solution 7 - C#JStrahlView Answer on Stackoverflow
Solution 8 - C#user1267054View Answer on Stackoverflow
Solution 9 - C#monsieurgutixView Answer on Stackoverflow