Convert time to UTC

I get mail archives with such dates in it.

Wed, 17 Dec 1997 13:36:23 +2
Mon, 16 Jun 1997 15:41:52 EST
Tue, 15 Jul 1997 14:37:00 EDT
Tue, 5 Aug 1997 08:37:56 PST
Tue, 5 Aug 1997 15:46:16 PDT
Thu, 5 Mar 1998 08:44:19 MET
Mon, 8 Nov 1999 17:49:25 GMT
Thu, 24 Feb 94 20:06:06 MST
Mon, 19 Dec 2005 14:17:06 CST
Thu, 14 Sep 95 19:15 CDT
Sat, 22 Feb 1997 05:16:55 UT
Mon, 8 Jul 1996 15:48:54 GMT-5
Mon, 25 Nov 1996 17:10:28 WET
Mon, 6 Jan 1997 23:43:48 UT
Fri, 13 Jun 1997 16:44:03 -0400

Ask is the time to convert to UTC. This is how I try to do it.

static void Main(string[] args)
{
    var possibleValues = new string[] 
    {
        "Mon, 29 Sep 2014 08:33:35 +0200"
        , "Fri, 29 Jun 2001 07:53:01 -0700"
        ,"Fri, 26 Sep 2014 15:57:04 +0000"
        ,"Wed, 17 Dec 1997 13:36:23 +2"
        , "Fri, 13 Jun 1997 16:44:03 -0400"

        , "Mon, 16 Jun 1997 15:41:52 EST"
        , "Tue, 15 Jul 1997 14:37:00 EDT"
        , "Tue, 5 Aug 1997 08:37:56 PST"
        , "Tue, 5 Aug 1997 15:46:16 PDT"
        , "Thu, 5 Mar 1998 08:44:19 MET"
        , "Mon, 8 Nov 1999 17:49:25 GMT"
        , "Thu, 24 Feb 94 20:06:06 MST"
        , "Mon, 19 Dec 2005 14:17:06 CST"
        , "Thu, 14 Sep 95 19:15:00 CDT"
        , "Sat, 22 Feb 1997 05:16:55 UT"
        , "Mon, 8 Jul 1996 15:48:54 GMT-5"
        , "Mon, 25 Nov 1996 17:10:28 WET"
        , "Mon, 6 Jan 1997 23:43:48 UT"

    };

    foreach (var item in possibleValues)
    {
        var dateParts = item.Split(' ');
        var lastItem = dateParts[dateParts.Length - 1];
        if (lastItem.StartsWith("+") || lastItem.StartsWith("-"))
        {
            try
            {
                DateTimeOffset offset = DateTimeOffset.Parse(item, CultureInfo.InvariantCulture);
                Debug.WriteLine("Input: {0}, UTC Time: {1}", item, offset.UtcDateTime);
            }
            catch (Exception exc)
            {
                Debug.WriteLine("Failed - {0}, Error Message: {1}", item, exc.Message);
            }
        }
        else
        {
            //Sometimes year is a two digit number and sometimes it is 4 digit number.
            string dateFormat = string.Format("ddd, {0} MMM {1} {2}:mm:ss {3}", new string('d', dateParts[1].Length), new string('y', dateParts[3].Length), int.Parse(dateParts[4].Substring(0, 2)) > 12 ? "HH" : "hh", lastItem);     
            try
            {
                DateTimeOffset offset = DateTimeOffset.ParseExact(item, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None);
                Debug.WriteLine("Input: {0}, UTC Time: {1}", item, offset.UtcDateTime);
            }
            catch (Exception exc)
            {
                Debug.WriteLine("Failed - {0}, DateFormat Tried: {1}, Error Message: {2}", item, dateFormat, exc.Message);
            }
        }
    }
}

I cannot figure out how to handle all cases. I am also open to using Noda time.

I went through a lot of links from SO and Google to find this answer, but could not implement any answer from these links. If you know a similar question, please let me know.

I already went through the links.

Convert.ToDateTime method
Converting between types
daylight-saving-time-and-time-zone-best-practices
SO Time zone tags
Encoding guidelines using DateTime in the .NET Framework
conversion-of-a-utc-date-time-string- in-c-sharp

+4
1

RFC 822 ยง5.1 RFC 1123 ยง5.2.14.

.

  • "WET" +0000
  • "MET" , +0100.
  • "GMT-5" "-0500"
  • "+ 2" "+0200"

:

  • "UT" / "GMT" = +0100
  • "EDT" = -0400
  • "EST" / "CDT" = -0500
  • "CST" / "MDT" = -0600
  • "MST" / "PDT" = -0700
  • "PST" = -0800

, . , 5 "CST", . . , "" , CST RFC822/1123. "+0800".

.NET RFC822/1123 "R" . DateTimeOffset.ParseExact DateTime.ParseExact "R". , - , "GMT", .

(DateTimeOffset.Parse DateTime.Parse), , , . , , .

private static readonly Dictionary<string,string> TZMap = new Dictionary<string, string>
{
    // Defined by RFC822, but not known to .NET
    {"UT", "+0000"},
    {"EST", "-0500"},
    {"EDT", "-0400"},
    {"CST", "-0600"},
    {"CDT", "-0500"},
    {"MST", "-0700"},
    {"MDT", "-0600"},
    {"PST", "-0800"},
    {"PDT", "-0700"},

    // Extraneous, as found in your data
    {"WET", "+0000"},
    {"MET", "+0100"}
};

public static DateTimeOffset Parse(string s)
{
    // Get the time zone part of the string
    var tz = s.Substring(s.LastIndexOf(' ') + 1);

    // Replace time zones defined in the map
    if (TZMap.ContainsKey(tz))
    {
        s = s.Substring(0, s.Length - tz.Length) + TZMap[tz];
    }

    // Replace time zone offsets with leading characters
    if (tz.StartsWith("GMT+") || tz.StartsWith("GMT-") || tz.StartsWith("UTC+") || tz.StartsWith("UTC-"))
    {
        s = s.Substring(0, s.Length - tz.Length) + tz.Substring(3);
    }

    DateTimeOffset dto;
    if (DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out dto))
    {
        return dto;
    }

    throw new ArgumentException("Could not parse value: " + s);
}

, , , , . , .

, , DateTimeOffset, UTC, .UtcDateTime .ToUniversalTime().

+3

All Articles