Check if a string is a valid date using DateTime.TryParse

C#.Net

C# Problem Overview


I am using DateTime.TryParse() function to check if a particular string is a valid datetime not depending on any cultures.
To my surprise , the function returns true for even strings like "1-1", "1/1" .etc.

How can I solve this problem?

Update:

Does it mean, if I want to check if a particular string is valid datetime, I need a huge array of formats?? There will be different combinations , I believe.
Even there are lots of date separator ( '.' , '/' , '-', etc..) depending on the culture, it will be difficult for me to define an array of format to check against .
Basically, I want to check if a particular string contains AT LEAST day(1 through 31 or 01 through 31),month(1 through 12 or 01 through 12) and year(yyyy or yy) in any order, with any date separator , what will be the solution?
So, if the value includes any parts of time, it should return true too. I could NOT be able to define a array of format.

C# Solutions


Solution 1 - C#

If you want your dates to conform a particular format or formats then use DateTime.TryParseExact otherwise that is the default behaviour of DateTime.TryParse

DateTime.TryParse

> This method tries to ignore unrecognized data, if possible, and > fills in missing month, day, and year information with the current > date. If s contains only a date and no time, this method assumes the > time is 12:00 midnight. If s includes a date component with a > two-digit year, it is converted to a year in the current culture's > current calendar based on the value of the Calendar.TwoDigitYearMax > property. Any leading, inner, or trailing white space character in s > is ignored.

If you want to confirm against multiple formats then look at DateTime.TryParseExact Method (String, String[], IFormatProvider, DateTimeStyles, DateTime) overload. Example from the same link:

string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                   "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                   "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                   "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                   "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM", 
                        "5/1/2009 6:32:00", "05/01/2009 06:32", 
                        "05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"}; 
DateTime dateValue;

foreach (string dateString in dateStrings)
{
   if (DateTime.TryParseExact(dateString, formats, 
                              new CultureInfo("en-US"), 
                              DateTimeStyles.None, 
                              out dateValue))
      Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
   else
      Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}
// The example displays the following output: 
//       Converted '5/1/2009 6:32 PM' to 5/1/2009 6:32:00 PM. 
//       Converted '05/01/2009 6:32:05 PM' to 5/1/2009 6:32:05 PM. 
//       Converted '5/1/2009 6:32:00' to 5/1/2009 6:32:00 AM. 
//       Converted '05/01/2009 06:32' to 5/1/2009 6:32:00 AM. 
//       Converted '05/01/2009 06:32:00 PM' to 5/1/2009 6:32:00 PM. 
//       Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM.

Solution 2 - C#

Use DateTime.TryParseExact() if you want to match against a specific date format

 string format = "ddd dd MMM h:mm tt yyyy";
DateTime dateTime;
if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture,
    DateTimeStyles.None, out dateTime))
{
    Console.WriteLine(dateTime);
}
else
{
    Console.WriteLine("Not a date");
}

Solution 3 - C#

[TestCase("11/08/1995", Result= true)]
[TestCase("1-1", Result = false)]
[TestCase("1/1", Result = false)]
public bool IsValidDateTimeTest(string dateTime)
{
    string[] formats = { "MM/dd/yyyy" };
    DateTime parsedDateTime;
    return DateTime.TryParseExact(dateTime, formats, new CultureInfo("en-US"),
                                   DateTimeStyles.None, out parsedDateTime);
}

Simply specify the date time formats that you wish to accept in the array named formats.

Solution 4 - C#

So this question has been answered but to me the code used is not simple enough or complete. To me this bit here is what I was looking for and possibly some other people will like this as well.

string dateString = "198101";

if (DateTime.TryParse(dateString, out DateTime Temp) == true)
{
     //do stuff
}

The output is stored in Temp and not needed afterwards, datestring is the input string to be tested.

Solution 5 - C#

An alternative is to create a method to validate that the text is of Date type.

public bool IsDateTime(string date)
{
	if (string.IsNullOrEmpty(date)) return false;
    return DateTime.TryParse(date, out DateTime dateTime);
}

Solution 6 - C#

> Basically, I want to check if a particular string contains AT LEAST day(1 through 31 or 01 through 31),month(1 through 12 or 01 through 12) and year(yyyy or yy) in any order, with any date separator , what will be the solution? So, if the value includes any parts of time, it should return true too. I could NOT be able to define a array of format.

When I was in a similar situation, here is what I did:

  1. Gather all the formats my system is expected to support.
  2. Looked at what is common or can be generalize.
  3. Learned to create REGEX (It is an investment of time initially but pays off once you create one or two on your own). Also do not try to build REGEX for all formats in one go, follow incremental process.
  4. I created REGEX to cover as many format as possible.
  5. For few cases, not to make REGEX extra complex, I covered it through DateTime.Parse() method.
  6. With the combination of both Parse as well as REGEX i was able to validate the input is correct/as expected.

This http://www.codeproject.com/Articles/13255/Validation-with-Regular-Expressions-Made-Simple was really helpful both for understanding as well as validation the syntax for each format.

My 2 cents if it helps....

Solution 7 - C#

Try using

DateTime.ParseExact(
    txtPaymentSummaryBeginDate.Text.Trim(),
    "MM/dd/yyyy", 
    System.Globalization.CultureInfo.InvariantCulture
);

It throws an exception if the input string is not in proper format, so in the catch section you can return false;

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
QuestionKaiView Question on Stackoverflow
Solution 1 - C#HabibView Answer on Stackoverflow
Solution 2 - C#Mudassir HasanView Answer on Stackoverflow
Solution 3 - C#User 12345678View Answer on Stackoverflow
Solution 4 - C#DeathstalkerView Answer on Stackoverflow
Solution 5 - C#Alexandre NeukirchenView Answer on Stackoverflow
Solution 6 - C#SBirthareView Answer on Stackoverflow
Solution 7 - C#Anil MohapatraView Answer on Stackoverflow