98

I have the following date in string format "2011-29-01 12:00 am" . Now I am trying to convert that to datetime format with the following code:

DateTime.TryParse(dateTime, out dt); 

But I am alwayws getting dt as {1/1/0001 12:00:00 AM} , Can you please tell me why ? and how can I convert that string to date.

EDIT: I just saw everybody mentioned to use format argument. I will mention now that I can't use the format parameter as I have some setting to select the custom dateformat what user wants, and based on that user is able to get the date in textbox in that format automatically via jQuery datepicker.

Rocky Singh
  • 15,128
  • 29
  • 99
  • 146
  • 4
    By the way, you can determine if the conversion failed by checking the return value of `TryParse`. That is `bool success = DateTime.TryParse(...);`. – Jim Mischel Jan 18 '11 at 00:01

7 Answers7

227

This should work based on your example "2011-29-01 12:00 am"

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 8
    Beat me to it. If you know the format of your input string you should virtually always use TryParseExact/ParseExact methods. – Euro Micelli Jan 17 '11 at 23:35
  • okay, so my date format is similar to the one in the example, but if the day or month value is single digit, then the DateTime parser will throw back an error, because its looked for two digits when there is only one. What would you suggest in this scenario? – Ciaran Gallagher Nov 23 '12 at 20:49
  • 13
    To answer my own question, in this case if you use a single character in the format, it works for both single and double character dates. e.g. d/m/yyyy works for 13/11/2012 – Ciaran Gallagher Nov 23 '12 at 20:56
  • @BrokenGlass this is not working for me Can you please help me with this – Meena Apr 05 '17 at 10:31
  • 2
    @CiaranGallagher Just a small remark, the date in your comment should use big M (d/M/yyyy) – Yusril Maulidan Raji May 31 '17 at 08:22
21

You need to use the ParseExact method. This takes a string as its second argument that specifies the format the datetime is in, for example:

// Parse date and time with custom specifier.
CultureInfo provider = CultureInfo.InvariantCulture;
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
try
{
   result = DateTime.ParseExact(dateString, format, provider);
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

If the user can specify a format in the UI, then you need to translate that to a string you can pass into this method. You can do that by either allowing the user to enter the format string directly - though this means that the conversion is more likely to fail as they will enter an invalid format string - or having a combo box that presents them with the possible choices and you set up the format strings for these choices.

If it's likely that the input will be incorrect (user input for example) it would be better to use TryParseExact rather than use exceptions to handle the error case:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

A better alternative might be to not present the user with a choice of date formats, but use the overload that takes an array of formats:

// A list of possible American date formats - swap M and d for European formats
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",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

If you read the possible formats out of a configuration file or database then you can add to these as you encounter all the different ways people want to enter dates.

The main drawback with this approach is that you will still have ambiguous dates. The formats are tried in order so no matter what it'll try the European format before the American (or vice versa) and cover anything where the day is less than 13 to a European formatted date even if the user thought they were entering an American formatted date.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
7

Try using safe TryParseExact method

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);
Marco Forberg
  • 2,634
  • 5
  • 22
  • 33
KateA
  • 651
  • 7
  • 8
4

From DateTime on msdn:

Type: System.DateTime% When this method returns, contains the DateTime value equivalent to the date and time contained in s, if the conversion succeeded, or MinValue if the conversion failed. The conversion fails if the s parameter is null, is an empty string (""), or does not contain a valid string representation of a date and time. This parameter is passed uninitialized.

Use parseexact with the format string "yyyy-dd-MM hh:mm tt" instead.

RedDeckWins
  • 2,111
  • 14
  • 16
3

That works:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Lucas S.
  • 537
  • 2
  • 7
  • 18
1
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Mehul Mistri
  • 15,037
  • 14
  • 70
  • 94
0

If you give the user the opportunity to change the date/time format, then you'll have to create a corresponding format string to use for parsing. If you know the possible date formats (i.e. the user has to select from a list), then this is much easier because you can create those format strings at compile time.

If you let the user do free-format design of the date/time format, then you'll have to create the corresponding DateTime format strings at runtime.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • That's right jim If you let the user do free-format design of the date/time format, then you'll have to create the corresponding DateTime format strings at runtime. – Pinal Apr 05 '14 at 11:06