Juice
Juice
The Better Browser
Subscribe
RSS
(What is this?)
Latest Comments
Email me Send me Feedback
Technorati Profile
Copyright 2003-4 Randy Charles Morin
Sat, 01 Jan 2005 05:46:18 GMT
RFC 822 and System.DateTime

I've always known that the .NET System.DateTime class had some limitations converting RFC 822 formatted date-times. Here's an example test case where the .NET library fails.

[NUnit.Framework.Test]
[NUnit.Framework.ExpectedException(
typeof(System.FormatException))]
public void Date4()
{
  
Convert.ToDateTime("Thu, 30 Dec 2004 13:52:52 -0500");
}

The problem is that .NET throws when parsing the timezone. And there are other situations where .NET parses the timezone but doesn't translate it correct. Here's an test case.

[NUnit.Framework.Test]
public void Date9()
{
   System.DateTime dt = Convert.ToDateTime("Thu, 30 Dec 2004 13:52:52 GMT").ToUniversalTime();
   System.Console.WriteLine(dt.ToString("r"));
   System.DateTime dt2 = Convert.ToDateTime("Thu, 30 Dec 2004 13:52:52");
  
if (dt2 != dt)
   {
      NUnit.Framework.Assert.Fail(dt.ToString("r")+"|"+dt2.ToString("r"));
   }
}

The solution was to write my own RFC 822 date parsing class that compensated for these limitations. I wrote a dozen test cases that seem to confirm it's better than the default .NET behavior. Feedback would be nice.

using System;

namespace kb
{
	public class Rfc822DateTime 
	{
		static public System.DateTime FromString(string date)
		{
			System.DateTime dt;
			int pos = date.LastIndexOf(" ");

			try
			{
				dt = Convert.ToDateTime(date);
				if (date.Substring(pos+1) == "Z")
				{
					dt = dt.ToUniversalTime();
				}
				else if (date.Substring(pos+1) == "GMT")
				{
					dt = dt.ToUniversalTime();
				}
				return dt;
			}
			catch (System.Exception x)
			{ 
				System.Diagnostics.Trace.WriteLine(x.Message);
			}
			
			dt = Convert.ToDateTime(date.Substring(0, pos));
			if (date[pos+1] == '+')
			{
				int h = Convert.ToInt32(date.Substring(pos+2, 2));
				dt = dt.AddHours(-h);
				int m = Convert.ToInt32(date.Substring(pos+4, 2));
				dt = dt.AddMinutes(-m);
			}
			else if (date[pos+1] == '-')
			{
				int h = Convert.ToInt32(date.Substring(pos+2, 2));
				dt = dt.AddHours(h);
				int m = Convert.ToInt32(date.Substring(pos+4, 2));
				dt = dt.AddMinutes(m);
			}
			else if (date.Substring(pos+1) == "A")
			{
				dt = dt.AddHours(1);
			}
			else if (date.Substring(pos+1) == "B")
			{
				dt = dt.AddHours(2);
			}
			else if (date.Substring(pos+1) == "C")
			{
				dt = dt.AddHours(3);
			}
			else if (date.Substring(pos+1) == "D")
			{
				dt = dt.AddHours(4);
			}
			else if (date.Substring(pos+1) == "E")
			{
				dt = dt.AddHours(5);
			}
			else if (date.Substring(pos+1) == "F")
			{
				dt = dt.AddHours(6);
			}
			else if (date.Substring(pos+1) == "G")
			{
				dt = dt.AddHours(7);
			}
			else if (date.Substring(pos+1) == "H")
			{
				dt = dt.AddHours(8);
			}
			else if (date.Substring(pos+1) == "I")
			{
				dt = dt.AddHours(9);
			}
			else if (date.Substring(pos+1) == "K")
			{
				dt = dt.AddHours(10);
			}
			else if (date.Substring(pos+1) == "L")
			{
				dt = dt.AddHours(11);
			}
			else if (date.Substring(pos+1) == "M")
			{
				dt = dt.AddHours(12);
			}
			else if (date.Substring(pos+1) == "N")
			{
				dt = dt.AddHours(-1);
			}
			else if (date.Substring(pos+1) == "O")
			{
				dt = dt.AddHours(-2);
			}
			else if (date.Substring(pos+1) == "P")
			{
				dt = dt.AddHours(-3);
			}
			else if (date.Substring(pos+1) == "Q")
			{
				dt = dt.AddHours(-4);
			}
			else if (date.Substring(pos+1) == "R")
			{
				dt = dt.AddHours(-5);
			}
			else if (date.Substring(pos+1) == "S")
			{
				dt = dt.AddHours(-6);
			}
			else if (date.Substring(pos+1) == "T")
			{
				dt = dt.AddHours(-7);
			}
			else if (date.Substring(pos+1) == "U")
			{
				dt = dt.AddHours(-8);
			}
			else if (date.Substring(pos+1) == "V")
			{
				dt = dt.AddHours(-9);
			}
			else if (date.Substring(pos+1) == "W")
			{
				dt = dt.AddHours(-10);
			}
			else if (date.Substring(pos+1) == "X")
			{
				dt = dt.AddHours(-11);
			}
			else if (date.Substring(pos+1) == "Y")
			{
				dt = dt.AddHours(-12);
			}
			else if (date.Substring(pos+1) == "EST")
			{
				dt = dt.AddHours(5);
			}
			else if (date.Substring(pos+1) == "EDT")
			{
				dt = dt.AddHours(4);
			}
			else if (date.Substring(pos+1) == "CST")
			{
				dt = dt.AddHours(6);
			}
			else if (date.Substring(pos+1) == "CDT")
			{
				dt = dt.AddHours(5);
			}
			else if (date.Substring(pos+1) == "MST")
			{
				dt = dt.AddHours(7);
			}
			else if (date.Substring(pos+1) == "MDT")
			{
				dt = dt.AddHours(6);
			}
			else if (date.Substring(pos+1) == "PST")
			{
				dt = dt.AddHours(8);
			}
			else if (date.Substring(pos+1) == "PDT")
			{
				dt = dt.AddHours(7);
			}

			return dt;
		}
	}
}
Permalink
Comments
+del.icio.us
Tell-a-Friend
Categories:  
Comments RSS
Tue, 17 Jan 2006 09:46:15 GMT
RFC 822 and System.DateTime
very good
Mon, 06 Feb 2006 15:10:08 GMT
RFC 822 and System.DateTime

excellent !
Thu, 23 Feb 2006 01:18:17 GMT
RFC 822 and System.DateTime
I can't believe .NET doesn't handle this properly.  Nice work!  I can really use this.
Thu, 04 Jan 2007 00:18:35 GMT
RFC 822 and System.DateTime

.Net does have this

DateTime.Now.ToString("r")

Comments Closed!