Just to provide a slightly different take on this, and give you an idea of some other options you have; you can specify the format to DateTime.Parse (or TryParse as in my example) to account for circumstances like this, without trying to 'pre format' the string into something else with String.Replace
calls and the like;
public DateTime ParseOrdinalDateTime(string dt)
{
string[] expectedFormats =
DateTime d;
if (DateTime.TryParseExact(dt, "dddd, d\"st\" MMMM yyyy", null, DateTimeStyles.None, out d))
return d;
if (DateTime.TryParseExact(dt, "dddd, d\"nd\" MMMM yyyy", null, DateTimeStyles.None, out d))
return d;
if (DateTime.TryParseExact(dt, "dddd, d\"rd\" MMMM yyyy", null, DateTimeStyles.None, out d))
return d;
if (DateTime.TryParseExact(dt, "dddd, d\"th\" MMMM yyyy", null, DateTimeStyles.None, out d))
return d;
throw new InvalidOperationException("Not a valid DateTime string");
}
The reason I'd propose this approach is that it sets out your input expectations very clearly, and contains the behaviour to a single method. If the format changes, you can just specify a different format string in here and account for a new date time string structure.
Or, a slight variation on the above, taking into account below comments;
private static DateTime ParseOrdinalDateTime(string dt)
{
string[] expectedFormats = new[]
{
"dddd, d'st' MMMM yyyy",
"dddd, d'nd' MMMM yyyy",
"dddd, d'rd' MMMM yyyy",
"dddd, d'th' MMMM yyyy"
};
try
{
return DateTime.ParseExact(dt, expectedFormats, null, DateTimeStyles.None);
}
catch (Exception e)
{
throw new InvalidOperationException("Not a valid DateTime string", e);
}
}
NOTE: The only reason I catch and throw an InvalidOperationException above is to protect the caller from having to catch Exception
to handle whatever possible exceptions DateTime.ParseExact
may throw. You could easily modify this API.