Obi
Obi

Reputation: 3091

Date conversion from Rss feeds

I am trying to aggregate several rss feeds and when I try to convert the publish date I get from the feedds, I get an exception as the date is in the following format 'Wed, 5 May 2010 14:27:37 BST'.

I have tried converting to Rfc822 datetime using a code snippet I found here but it still won't work (for obviousreasons). Does anyone know how I can convert this to a DateTime object in .Net

Upvotes: 2

Views: 174

Answers (2)

eFloh
eFloh

Reputation: 2158

I wrote a little snippet, not supporting all formats, but many. I would be happy to receive feedback or improvements...

    /// <summary>
    /// Parst ein Datum aus dem angegebenen XML Element.
    /// Der Inhalt muss RFS 822, Kap. 5 entsprechen.
    /// </summary>
    /// <param name="current">Das Element mit dem RFS822-Datum (kann null sein, um null auszugeben)</param>
    /// <returns>geparstes Datum oder null, wenn current==null ist.</returns>
    /// <remarks>Unterstützt momentan die Zeitzonen-Angabe nur numerisch oder als UT/GMT, nicht als Mil-Zone oder TLA.</remarks>
    private static DateTime? ParseRfc822DateTime(XElement current)
    {
        DateTime? result = null;
        if (current != null)
        {
            Regex datePattern = new Regex(@"((Mon|Thu|Wed|Thu|Fri|Sat|Sun)\s*,\s*)?([0-9]{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*([0-9]{2,4})\s*([0-9]{2}):([0-9]{2})(:([0-9]{2}))?(.*)", RegexOptions.Singleline);

            Match match = datePattern.Match(current.Value);
            if (match.Success)
            {
                string dayIndi = match.Groups[2].Value;
                int day = int.Parse(match.Groups[3].Value);
                string monText = match.Groups[4].Value;
                int year = int.Parse(match.Groups[5].Value);
                int hour = int.Parse(match.Groups[6].Value);
                int min = int.Parse(match.Groups[7].Value);
                int sec = match.Groups[8].Success ? int.Parse(match.Groups[9].Value) : 0;
                string timezoneIndi = (match.Groups[10].Value ?? String.Empty).Trim();

                if (year < 99)
                {
                    year = System.Globalization.CultureInfo.InvariantCulture.Calendar.ToFourDigitYear(year);
                }

                result = DateTime.ParseExact(String.Format(
                    "{0:00}.{1}.{2:0000} {3:00}:{4:00}:{5:00}",
                    day, monText, year, hour, min, sec),
                    "dd.MMM.yyyy HH:mm:ss",
                    System.Globalization.CultureInfo.InvariantCulture,
                    System.Globalization.DateTimeStyles.AssumeLocal);
                result = DateTime.SpecifyKind(result.Value, DateTimeKind.Unspecified);

                TimeZoneInfo zoneInfo;
                if (timezoneIndi == "UT" || timezoneIndi == "GMT")
                {
                    zoneInfo = TimeZoneInfo.Utc;
                }
                else if (timezoneIndi.StartsWith("+") || timezoneIndi.StartsWith("-"))
                {
                    int hoursOffset = int.Parse(timezoneIndi.Substring(1, 2));
                    int minsOffset = int.Parse(timezoneIndi.Substring(3, 2));

                    if (timezoneIndi.StartsWith("-"))
                    {
                        hoursOffset = -hoursOffset;
                        minsOffset = -minsOffset;
                    }

                    zoneInfo = TimeZoneInfo.CreateCustomTimeZone("RFC822-Offset" + timezoneIndi,
                        new TimeSpan(hoursOffset, minsOffset, 0), "RFS822-Offset" + timezoneIndi, timezoneIndi);

                    //result = result.Value.AddMinutes(minsOffset).AddHours(hoursOffset);
                }
                else
                {
                    /* This WILL fail for the MIL-One-Letter-Zones and some others. */
                    zoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timezoneIndi);
                }

                result = TimeZoneInfo.ConvertTime(result.Value, zoneInfo, TimeZoneInfo.Local);

                return result;
            }
        }

        return result;
    }

Upvotes: 1

Fischermaen
Fischermaen

Reputation: 12458

"BST" in time means British Summer Time, Brazil Standard Time or Bering Summer Time. If you know the time zone in which the time was "encoded" you can get it for parsing it. I assumed British Summer Time in my sample:

var date = DateTime.Parse("Wed, 5 May 2010 14:27:37", CultureInfo.GetCultureInfo("En-GB"));

Just "kill" the Word "BST" from end of the time string and get Britsh culture info to parese the date and time.

Upvotes: 1

Related Questions