How do I use DateTime.TryParse with a Nullable<DateTime>?
Solution 1
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 2
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 3
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 4
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 5
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;
}
}
Ram Rachum
Web developer and Microsoft MVP. Founder of the Red River .NET User Group.
Updated on April 15, 2021Comments
-
Ram Rachum about 3 years
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?
-
Ram Rachum over 15 yearsYou're right, I was looking for more of a one-liner to get it done, but I suppose this will do. Don't like creating that temp variable, feels messy. :-/ Seems like this scenario should be better supported.
-
David Alpert over 15 yearssee Binary Worrier's suggestion to psuedo-inline that into an extension method.
-
Aaron Powell over 15 yearsWhy are you casting a DateTime to a DateTime? You don't need to recased d2 before passing it into the TryParse.
-
Raymond over 15 yearsYa dont wanna init the date [as you're using it as an out param] OK, I'll stop being picky!
-
Raymond over 15 yearsDont have compiler on me, but as DateTime is a value type, does the extension method def compile?
-
Raymond over 15 yearsResult doesnt come back unless you make it out -- [TestFixture] public class WhenExtending { [Test] public void TryParseShouldWork() { DateTime? x = null; var res = Externders.TryParse( x, "1/1/1990" ); Assert.IsTrue( res )
-
Raymond over 15 years;Assert.That( x != null ); } } fails on the Assert.That, i.e., the result doesnt get modified as DateTime is a value type (which is always a nice weed-out question on phone screens :D)
-
Raymond over 15 years(obv the first (non-extension) one will work, but it should be out, not ref - and you should be nulling the result if it fails to fit in with TryXXX APIs in general - Pretty sure FDG mentions that. Man, am I picky!
-
Rabeel over 15 yearsWell obviously the samples shown are for illustration purposes . . . (and Ruben STOP NIT PICKING YA BAD HOOR!)
-
Rabeel over 15 yearsP.S. . . . and what are these "Tests" and "Asserts" of which you speak? (Tell Me Of Your Home World Usul)
-
Rabeel over 15 yearsRuben: You're right mate, an extension method won't work for this (or any other value type). Well spotted . . . cough ya bad hoor cough
-
Drew Noakes about 14 years@Slace -- I updated the answer to incorporate your suggestion.
-
Mike Zboray over 11 yearsWhat is that first parameter,
dateTime
, for? It is never used. -
Pimenta over 11 years@Jason Kealey I hope this is already introduced in VS2012, otherwise I will have to continue using this good piece of code.
-
Erik Funkenbusch over 11 years@mikez - that's how how extension methods work, it's used by the compiler to know that it should be an extension method.
-
Mike Zboray over 11 years@MystereMan I know what an extension method is. A more appropriate signature for an extension method would be
DateTime? TryParse(this string dateString)
. This implementation is just bizarre. -
Erik Funkenbusch over 11 years@mikez - then why did you ask what it was for? Why pollute the string namespace when you only need it for datetime? The purpose is to provide an analog to DateTime.TryParse that is DateTime?.TryParse
-
Myster about 9 yearsI probably shouldn't argue with The Skeet, but... you should call your method Parse, since I would expect a method called TryParse to follow the TryParse convention and return a boolean. ;-)
-
Jon Skeet about 9 years@Myster: Well in neither case does it follow the exact existing convention - those used to just
Parse
would expect it to returnDateTime
and throw an exception on failure, right? But yes, you can do whatever you want... and in Noda Time, I have named the relevant methodsParse
instead. -
Jeppe Stig Nielsen over 7 yearsThe
else
keyword is unnecessary (in your first example) since the end-point of theif
block can never be reached. -
Jeppe Stig Nielsen over 7 years@ErikFunkenbusch This extension method will not allow a call syntax like
(DateTime?).TryParse( ... )
orNullable<DateTime>.TryParse( ... )
. So mike z is right, this is a silly signature for the method. -
Jon Skeet over 7 years@JeppeStigNielsen: Yes, it's unnecessary - but it may be stylistically preferable for symmetry. It's just a personal preference (and I'm not consistent, either...)
-
Erik Funkenbusch over 7 years@JeppeStigNielsen - You apparently don't understand how extension methods work. You don't call them like static methods. You call them like normal methods, like
variablename.TryParse()
, nottypename.TryParse()
-
Jeppe Stig Nielsen over 7 years@ErikFunkenbusch Yes, you are right. The discussion here is what is the use of
this DateTime? dateTime
when that parameter is not used in the method body? This is the original question by mike z. If one were to use the method of this answer, one should do this:DateTime? dummy = null; DateTime? result; var isSuccess = dummy.TryParse("some date text", out result);
. Otherwise one should assign a value to theout
variable first, and use theout
variableresult
as the "special"this
argument as well, which seems strange. So can we answer mike z's first comment in a better way? -
Kiquenet about 7 yearsAvoid Arrowhead anti-pattern
else { return null; }
byreturn null;
View: blog.codinghorror.com/flattening-arrow-code -
Jon Skeet about 7 years@Kiquenet: using else makes it clearer that one or the other path will be taken, and both return. I'm against massively nested code, but in this case it's really not a problem IMO.
-
cpcolella over 4 years@robnick How is that different than what i said?
-
robnick over 4 yearsIgnore my previous comment (I have upvoted your solution!), for latest C# I needed to cast the null: DateTime? d = DateTime.TryParse(blah, out DateTime dt) ? dt : (DateTime?)null;
-
cpcolella about 3 yearsso...you just copied my answer 4 months later?