tags:

views:

385

answers:

7

How can I convert the following strings to a System.DateTime object?

Wednesday 13th January 2010
Thursday 21st January 2010
Wednesday 3rd February 2010

Normally something like the following would do it

DateTime dt;
DateTime.TryParseExact(value, "dddd d MMMM yyyy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dt);

but this doesn't work because of the 'th', 'st' or 'rd' in the string

Update

It appears that DateTime doesn't support formatting the 'th', 'st', 'rd' etc so they need to be stripped before parsing. Rubens Farias provides a nice regular expression below.

A: 

Cant you strip out the st th rd using some sort of string replace or stringbuilder class then convert to date?

JonH
Why was this downvoted ?
JonH
I don't know why it was downvoted, but if you gave an example, I would upvote.
John Saunders
A: 

How about cleaning up those bits before using try parse:

string value = "Wednesday 13th January 2010";
value = value.Replace("th "," ").Replace("rd "," ").Replace("st "," ");
DateTime dt;
DateTime.TryParse(value,  out dt);
Paul Sasik
what if in the current culture, the day or month name contains "st", "nd" or "rd" ? You need a regex to do that properly...
Thomas Levesque
doesn't works on Augu*st*, Satu*rd*ay, Su*nd*ay, Mo*nd*ay
Rubens Farias
I included a space in the replace calls for that reason... so that only the ends of words would be evaluated. Similar to the RegEx word boundary idea.
Paul Sasik
Still nails Augu*st
Lazarus
Paul Sasik
@Lazarus: Good eye. RegEx wins.
Paul Sasik
Replace August with something, i'll update mine :P
Chris S
+11  A: 

What about strip them?

string value = "Wednesday 13th January 2010";
DateTime dt;
DateTime.TryParseExact(
    Regex.Replace(value, @"(\w+ \d+)\w+ (\w+ \d+)", "$1 $2"),
    "dddd d MMMM yyyy", 
    DateTimeFormatInfo.InvariantInfo, 
    DateTimeStyles.None, out dt);
Rubens Farias
Okay, so your Regex appears to be working fine and stripping out the 'th', 'st' etc but for some reason the DateTime parsing is still failing. Am I missing something? Culture maybe? Does this work for you?
David G
Note that the formatter for the full day name in .NET is `dddd`, lowercase. I've edited your answer to reflect this, Rubens.
Wim Hollebrandse
Works great now and a nice solution
David G
Note that The 'dd' in the format should be a single 'd', "dddd d MMMM yyyy", otherwise single digit dates fail. I haven't got the rep to edit it.
David G
@DaveG, nice point, fixed
Rubens Farias
A: 

No credit to me but this looks interesting for general DataTime parsing: http://www.codeproject.com/KB/datetime/date_time_parser_cs.aspx?msg=3299749

Lazarus
A: 

I remembered this post on using MGrammar to parse a lot of different ways to express dates and times. It doesn't exactly answer your question, but it might serve as a useful base depending on what your ultimate goal is.

Nick
+1  A: 

Where does "th", "st","nd" or "rd" appear below?

  • mo*nd*ay
  • tuesday
  • wednesday
  • *th*ursday
  • friday
  • satu*rd*ay
  • su*nd*ay

  • january

  • february
  • march
  • april
  • may
  • june
  • july
  • augu*st*
  • september
  • october
  • november
  • december

However you know those 4 will always be followed by a space. So unless I've missed something, a simple

value = value.Replace("August","Augus").Replace("nd ","").Replace("st ","").Replace("nd ","").Replace("rd ","").Replace("Augus","August");
DateTime dt;
DateTime.TryParseExact(value,"DDDD dd MMMM yyyy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dt);
Chris S
+2  A: 

Another approach.

string sDate = "Wednesday 13th January 2010";
string[] sFields = sDate.Split (' ');
string day = sFields[1].Substring (0, (sFields[1].Length - 2));
DateTime date = new DateTime (sFields[3], sFields[2], day);
kenny