Преобразование даты из RSS-каналов

#.net #datetime #rss

#.net #дата-время #RSS-канал

Вопрос:

Я пытаюсь объединить несколько rss-каналов, и когда я пытаюсь преобразовать дату публикации, которую я получаю из feedds, я получаю исключение, поскольку дата находится в следующем формате 'Wed, 5 May 2010 14:27:37 BST' .

Я попытался преобразовать в Rfc822 datetime, используя фрагмент кода, который я нашел здесь, но он все равно не будет работать (по очевидным причинам). Кто-нибудь знает, как я могу преобразовать это в объект DateTime в .Net

Комментарии:

1. Привет, я нашел ответ здесь hashfactor.wordpress.com/2009/02/02 /… класс работает отлично и не выдает никаких неожиданных исключений. Мне нужно было только создать класс в соответствии с инструкциями, и это сработало 🙂

Ответ №1:

Я написал небольшой фрагмент, поддерживающий не все форматы, но многие. Я был бы рад получить отзывы или улучшения…

     /// <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 resu<
            }
        }

        return resu<
    }
  

Ответ №2:

«BST» по времени означает британское летнее время, Бразильское стандартное время или Берингово летнее время. Если вы знаете часовой пояс, в котором было «закодировано» время, вы можете получить его для синтаксического анализа. Я предположил, что в моем примере британское летнее время:

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

Просто «уберите» слово «BST» из конца строки времени и получите информацию о культуре Британцев, чтобы уточнить дату и время.

Комментарии:

1. Спасибо, но поскольку это происходит из RSS-канала, я не могу знать, что это всегда будет BST или что B будет Бразилия, Великобритания или Берингия! Но все равно спасибо.