views:

166

answers:

1

I have an application written in .NETMF that requires that I be able to parse an RFC822-Datetime.

Normally, this would be easy, but NETMF does not have a DateTime.parse() method, nor does it have some sort of a pattern matching implementation, so I'm pretty much stuck.

Any ideas?

EDIT: "Intelligent" solutions are probably needed. Part of the reason this is difficult is that the datetime in question has a tendency to have extra spaces in it (but only sometimes). A simple substring solution might work one day, but fail the next when the datetime has an extra space somewhere between the parts. I do not have control over the datetime, it is from the NOAA.

+3  A: 

Good ol' string manipulation:

Sun, 06 Jun 2010 20:07:44 +0000
          1         2         3
0123456789012345678901234567890
string x = Sanitize("  Sun,  06 \t Jun 2010 \r\n 20:07:44 +0000  ");

int day    = int.Parse(x.Substring(5, 2));
int month  = Array.IndexOf(months, x.Substring(8, 3)) + 1;
int year   = int.Parse(x.Substring(12, 4));

int hour   = int.Parse(x.Substring(17, 2));
int minute = int.Parse(x.Substring(20, 2));
int second = int.Parse(x.Substring(23, 2));

int offsetSgn    = (x[26] == "-") ? -1 : 1;
int offsetHour   = int.Parse(x.Substring(27, 2));
int offsetMinute = int.Parse(x.Substring(29, 2));

DateTime result = new DateTime(year, month, day, hour, minute, second, 0);
TimeSpan offset = new TimeSpan(offsetHour, offsetMinute, 0);

// TODO: add offset...

with

string[] months = new string[12];
months[0] = "Jan";
months[1] = "Feb";
months[2] = "Mar";
months[3] = "Apr";
months[4] = "May";
months[5] = "Jun";
months[6] = "Jul";
months[7] = "Aug";
months[8] = "Sep";
months[9] = "Oct";
months[10] = "Nov";
months[11] = "Dec";

and

string Sanitize(string s)
{
    if (s == null)
    {
        return null;
    }

    char[] buffer = new char[s.Length];
    int pos = 0;
    bool inSpace = true;

    for (int i = 0; i < s.Length; i++)
    {
        if (s[i] == ' ' || s[i] == '\t' || s[i] == '\r' || s[i] == '\n')
        {
            if (!inSpace)
            {
                buffer[pos] = ' ';
                pos++;
                inSpace = true;
            }
        }
        else
        {
            buffer[pos] = s[i];
            pos++;
            inSpace = false;
        }
    }

    return new string(buffer, 0, pos);
}
dtb
This is good, but one thing I forgot to mention is that the datetime that I am parsing has been known to sometimes have extra spaces in it (Don't ask. It's an NOAA XML METAR. I have no idea WTF). I had a solution in PHP that would intelligently go through and attempt to figure out what part each of the dt was. I guess if I can't do that, a solution like this is my only option, although I wish NETMF had even a simple pattern matching class.
chris12892
Just zap all spaces with string.Replace(" ", "")
Hans Passant
The spaces are the only deliminator, so zapping them all isn't an option. That only makes the problem worse, maybe impossible without a proper pattern matching implementation. EDIT: Oh wait, I see your point. Yeah, that might also be an option.
chris12892
Awesome, that works. Thanks!
chris12892
You may want to add some error checking to make sure the sanitized string is indeed in the right format. Also, don't forget to adjust `result` for the timezone offset. Look at the spec if my code really covers all valid inputs or if, for example, `+0000` can also be expressed as `UTC` or `GMT`.
dtb
In this case, I do know that the string will always be expressed in the +0000 format. I am definitely going to extend this, but all I needed was a sharp prod in the right direction, which your post definitely gave me :) Thanks again.
chris12892