4

I have reviewed the answer to Parse very long date format to DateTime in C# and it goes a little way to fixing my problem, but I fear I might be stumbling into an unrelated issue, and thus have opened this new thread.

Dates come into my process as a string that I have no control over. They always represent a date in the future. An example would be "Wednesday 26th November at 18:30". Notice, the day has an ordinal, and that there is no year.

I need to get these into a DateTime structure, so that I can... well, do DateTime things to them!

I am currently using the following snippet (adjusted from the afore mentioned question), but it's still failing on the last conditional, which I would expect it to pass.

public DateTime ParseOrdinalDateTime(string dt)
{
    DateTime d;
    if (DateTime.TryParseExact(dt, "dddd d\"st\" MMMM \"at\" hh:mm", null, DateTimeStyles.AssumeLocal, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd d\"nd\" MMMM \"at\" hh:mm", null, DateTimeStyles.AssumeLocal, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd d\"rd\" MMMM \"at\" hh:mm", null, DateTimeStyles.AssumeLocal, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd d\"th\" MMMM \"at\" hh:mm", null, DateTimeStyles.AssumeLocal, out d))
        return d;

    throw new InvalidOperationException("Not a valid DateTime string");
}
Community
  • 1
  • 1
belial
  • 321
  • 1
  • 8
  • 3
    The answer below fixes your problem, but remember that TryParseExact accepts also an array of formats strings. Creating the array of the expected formats and passing it instead of calling 4 times TryParseExact should improve the readability of your code. – Steve Nov 02 '14 at 08:52
  • 2
    Thanks Steve. Yes I had noticed that, but not being a confident C# developer yet, I wanted to exclude that as being the issue, and wanted to focus down on the individual tests being applied. I will now combine my format masks into a String array, as suggested. – belial Nov 02 '14 at 09:14
  • One thing I'm not clear on, is how it then picks the year part of the date. Is the parser clever enough to determine this based on the DayOfWeek and DayOfMonth field? Will it always pick a date in the future? C# foo required beyond my skill to test this I think. – belial Nov 03 '14 at 08:20
  • Ok, it seems to assume DateTime.Now. Which is going to cause some problems nearer Christmas for me... I'll sort it out! ;) – belial Nov 03 '14 at 08:31

3 Answers3

3

If you're receiving a 24h format time, then you should parse the string as "dddd d\"th\" MMMM \"at\" HH:mm" (notice the uppercase Hs).

Arturo Torres Sánchez
  • 2,751
  • 4
  • 20
  • 33
2

1) Swap the hh:mm to HH:mm (using 24 hours..)
2) Set culture to en-US

Such as

string dateString = "Wednesday 26th November at 18:30";  
string format = "dddd d\"th\" MMMM \"at\" HH:mm";  
DateTime dt;
DateTime.TryParseExact(dateString, format, new CultureInfo("en-US"), DateTimeStyles.AssumeLocal, out dt);

edit - formatted

tglanz
  • 21
  • 3
1

Your format string is a little bit off and you need to set a culture:

private static void Main(string[] args)
{
    DateTime result = ParseOrdinalDateTime("Friday 29th August at 18:30");
}

public static DateTime ParseOrdinalDateTime(string dt)
{
    DateTime d;

    if (DateTime.TryParseExact(dt, "dddd d\"th\" MMMM \"at\" HH:mm",  CultureInfo.CreateSpecificCulture("en-GB"), DateTimeStyles.AssumeLocal, out d))
    {
        return d;
    }

    throw new InvalidOperationException("Not a valid DateTime string");
}
krystan honour
  • 6,523
  • 3
  • 36
  • 63
  • Yes thanks for that addition of the CultureInfo. I did stumble on that, but again wanted to reduce the likelihood that this was the reason my format parsing was the issue. I'm still flabbergasted that C# has no support for dates (or numbers for that matter) with ordinals built in... especially if we go through the rigmarole of adding the CultureInfo! – belial Nov 03 '14 at 08:13