Parsing very long DateTime format in C #

How would I parse the following string date for a DateTime object in C #:

"Thursday 1st January 1970"

It comes from XML feed and DateTime.Parse doesn't seem to like the en-GB locale. The feed will only ever be from a UK server, so I won't worry about globalization issues.

My initial brute force approach:

  • Remove everything before the comma and include it, and the trailing space will leave "Jan 1, 1970".
  • Then remove "st", "nd", "rd" or "th" to leave "January 1st 1970"
  • Then convert the month to its numeric equivalent, leaving "1 1 1970"
  • Then replace spaces with "/" to get "1/1/1970"

I'm sure there must be a much more elegant way? I couldn't get DateTime.Prse or Datetime.ParseExact to work

+2


source to share


3 answers


Just to give it a little thought and give you an idea of ​​some of the other options you have; you can specify the DateTime.Parse format (or TryParse as in my example) to accommodate such circumstances without trying to "preformat" the string to something else using calls String.Replace

or 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 suggest this approach is because it spells out your input expectations very clearly and contains behavior for a single method. If the format changes, you can simply specify a different format string here and create a new date string string.



Or a slight variation of the above, taking into account the following 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 will catch and throw the InvalidOperationException above is to protect the caller from catch Exception

handling any possible exceptions DateTime.ParseExact

. You can easily change this API.

+5


source


I don't believe that parsing DateTime

knows nothing about ordinals, but it should be able to handle everything else. Thus, you can use:

public static string RemoveOrdinals(string input)
{
    // Ugly but oh so simple.
    return input.Replace("0th", "0")
                .Replace("1st", "1")
                .Replace("2nd", "2")
                .Replace("3rd", "3")
                .Replace("11th", "11") // Need to handle these separately...
                .Replace("12th", "12")
                .Replace("13th", "13")
                .Replace("4th", "4")
                .Replace("5th", "5")
                .Replace("6th", "6")
                .Replace("7th", "7")
                .Replace("8th", "8")
                .Replace("9th", "9");
}

      

Then:



string text = RemoveOrdinals(text);
DateTime date = DateTime.ParseExact(text, "dddd, d MMMM yyyy",
                                    CultureInfo.GetCulture("en-GB"));

      

(As a quick plugin, of course you only want date and not date / time. Unfortunately .NET doesn't have this type to represent this, but you could use Noda TimeLocalDate

in my library . We don't handle ordinals either - that's all is equal anyway, so you need an extra method. Let me know if you want to see the relevant code though.)

+6


source


Use DateTime.Parse

with a culture specific format:

http://msdn.microsoft.com/en-us/library/kc8s65zs.aspx

The first reverse logic in this answer is to remove "st", "nd", etc. from the day of the month:

fooobar.com/questions/366361 / ...

Then just use DateTime.Parse

generally:

var result = DateTime.Parse("Thursday, 1 January 1970", new CultureInfo("en-GB"));

      

0


source







All Articles