Home All Groups Group Topic Archive Search About

question re: date format in RSS news feeds

Author
13 Jan 2006 5:55 PM
Milsnips
hi there,

i am trying to get some feeds into my site, but am having problems with the
converting the date format of "pubDate" into a datetime variable:

<pubDate>Wed, 28 Sep 2005 08:00:00 UT</pubDate>

It doesnt seem to like it? Any help appreciated

thanks,
Paul

Author
13 Jan 2006 9:43 PM
S. Justin Gengo [MCP]
Paul,

I wish I could remember where this code is actually from. I've searched and
can't find/remember the website. But it's from a gentleman who wrote an rss
feed aggregator. His biggest complaint was the lack of a standardized date
between types of feeds. Part of his code was this date class which he uses
to standardize the dates (He gives it away free and says it's ok to modify
so I'm posting it here. I'm going to keep searching for the site he put it
out on):


Imports Microsoft.VisualBasic

Namespace RssComponents

    Public Class DateTimeExt

        Private Shared regExpression As String =
"\s*(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)" & _
            "\s*,\s*)?(\d{1,2})\s+(Jan|Feb|Mar|Apr|May|Jun" & _
            "|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{2,})\s+(\d{2})\s*:\s*(\d{2})\s*(?::\s*(\d{2}))?"
& _
            "\s+([+\-]\d{4}|UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])"
        Private Shared rfc2822 As Regex = New Regex(regExpression,
RegexOptions.Compiled)
        Private Shared months As New ArrayList(New String() _
            {"ZeroIndex", "Jan", "Feb", "Mar", "Apr", "May", "Jun", _
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"})

        'private static TimeSpan dayLightDelta =
TimeZone.CurrentTimeZone.GetDaylightChanges(DateTime.Now.Year).Delta

        ''' <summary>
        ''' Converts an ISO 8601 date to a DateTime object. Helper method
needed to
        ''' deal with timezone offset since they are unsupported by the
        ''' .NET Framework.
        ''' </summary>
        ''' <param name="datetime">DateTime string</param>
        ''' <returns>DateTime instance</returns>
        ''' <exception cref="FormatException">On format errors parsing the
datetime</exception>
        Public Shared Function ToDateTime(ByVal datetime As String) As
DateTime

            Dim timeIndex As Integer = datetime.IndexOf(":")

            If timeIndex <> -1 Then

                Dim tzoneIndex As Integer = datetime.IndexOf("-", timeIndex)

                If tzoneIndex = -1 Then
                    tzoneIndex = datetime.IndexOf("+", timeIndex)
                    If tzoneIndex <> -1 Then 'timezone is ahead of UTC
                        Return AddOffset("+", datetime, tzoneIndex)

                    End If

                Else 'timezone is behind UTC

                    Return AddOffset("-", datetime, tzoneIndex)
                End If


            End If

            Return System.Xml.XmlConvert.ToDateTime(datetime,
"yyyy-MM-ddTHH:mm:sszzzzzz")

        End Function

        ''' <summary>
        ''' Parse is able to parse RFC2822/RFC822 formatted dates.
        ''' It has a fallback mechanism: if the string does not match,
        ''' the normal DateTime.Parse() function is called.
        ''' </summary>
        ''' <param name="dateTimeString">DateTime String to parse</param>
        ''' <returns>DateTime instance</returns>
        ''' <exception cref="FormatException">On format errors parsing the
datetime</exception>
        Public Shared Function Parse(ByVal dateTimeString As String) As
DateTime

            If dateTimeString = Nothing Then
                Return DateTime.Now.ToUniversalTime()
            End If

            If dateTimeString.Trim().Length = 0 Then
                Return DateTime.Now.ToUniversalTime()
            End If

            Dim m As Match = rfc2822.Match(dateTimeString)
            If m.Success Then

                Try
                    Dim dd As Integer = Int32.Parse(m.Groups(1).Value)
                    Dim mth As Integer = months.IndexOf(m.Groups(2).Value)
                    Dim yy As Integer = Int32.Parse(m.Groups(3).Value)
                    ' following year completion is compliant with RFC 2822.
                    'yy = (yy < 50 ? 2000 + yy: (yy < 1000 ? 1900 + yy: yy))
                    Dim hh As Integer = Int32.Parse(m.Groups(4).Value)
                    Dim mm As Integer = Int32.Parse(m.Groups(5).Value)
                    Dim ss As Integer = Int32.Parse(m.Groups(6).Value)
                    Dim zone As String = m.Groups(7).Value

                    Dim xd As New DateTime(yy, mth, dd, hh, mm, ss)

                    Return xd.AddHours(RFCTimeZoneToGMTBias(zone) * -1)
                Catch ex As Exception

                    Throw New
FormatException("RES_ExceptionRFC2822ParseGroupsMessage")
                End Try
            Else
                ' fallback, if regex does not match:
                Return DateTime.Parse(dateTimeString)

            End If
        End Function

        Private Sub New()
            'constructor is new to prevent creation, we just need the
statics
        End Sub


        Private Structure TZB
            Public Sub New(ByVal z As String, ByVal b As Integer)
                Zone = z
                Bias = b
            End Sub

            Public Zone As String
            Public Bias As Integer
        End Structure

        Private Const timeZones As Integer = 34
        Private Shared ZoneBias As TZB() = New TZB(timeZones) { _
            New TZB("GMT", 0), New TZB("UT", 0), _
            New TZB("EST", -5 * 60), New TZB("EDT", -4 * 60), _
            New TZB("CST", -6 * 60), New TZB("CDT", -5 * 60), _
            New TZB("MST", -7 * 60), New TZB("MDT", -6 * 60), _
            New TZB("PST", -8 * 60), New TZB("PDT", -7 * 60), _
            New TZB("Z", 0), New TZB("A", -1 * 60), _
            New TZB("B", -2 * 60), New TZB("C", -3 * 60), _
            New TZB("D", -4 * 60), New TZB("E", -5 * 60), _
            New TZB("F", -6 * 60), New TZB("G", -7 * 60), _
            New TZB("H", -8 * 60), New TZB("I", -9 * 60), _
            New TZB("K", -10 * 60), New TZB("L", -11 * 60), _
            New TZB("M", -12 * 60), New TZB("N", 1 * 60), _
            New TZB("O", 2 * 60), New TZB("P", 3 * 60), _
            New TZB("Q", 4 * 60), New TZB("R", 3 * 60), _
            New TZB("S", 6 * 60), New TZB("T", 3 * 60), _
            New TZB("U", 8 * 60), New TZB("V", 3 * 60), _
            New TZB("W", 10 * 60), New TZB("X", 3 * 60), _
            New TZB("Y", 12 * 60)}

        Private Shared Function RFCTimeZoneToGMTBias(ByVal zone As String)
As Double

            Dim s As String

            If zone.IndexOfAny(New Char() {"+"c, "-"c}) = 0 Then  ' +hhmm
format

                Dim fact As Integer
                If zone.Substring(0, 1) = "-" Then
                    fact = -1
                Else
                    fact = 1
                End If

                s = zone.Substring(1).TrimEnd()
                Dim hh As Double = Math.Min(23, Int32.Parse(s.Substring(0,
2)))
                Dim mm As Double = Math.Min(59, Int32.Parse(s.Substring(2,
2))) / 60
                Return fact * (hh + mm)
            Else
                ' named format
                s = zone.ToUpper().Trim()
                For i As Integer = 0 To timeZones
                    If (ZoneBias(i).Zone.Equals(s)) Then
                        Return ZoneBias(i).Bias / 60
                    End If
                Next

            End If

            Return 0.0
        End Function

        Private Shared Function AddOffset(ByVal offsetOp As String, ByVal
datetimeString As String, ByVal tzoneIndex As Integer) As DateTime

            Dim offset As String() = datetimeString.Substring(tzoneIndex +
1).Split(New Char() {":"c})
            Dim original As String = datetimeString
            datetimeString = datetimeString.Substring(0, tzoneIndex)

            If (datetimeString.IndexOf(":") =
datetimeString.LastIndexOf(":")) Then 'check if seconds part is missing
                datetimeString = datetimeString + ":00"
            End If

            Dim toReturn As DateTime =
System.Xml.XmlConvert.ToDateTime(datetimeString,
"yyyy-MM-ddTHH:mm:sszzzzzz")

            Try
                Select Case offsetOp
                    Case "+"
                        toReturn = toReturn.Subtract(New
TimeSpan(Int32.Parse(offset(0)), Int32.Parse(offset(1)), 0))
                    Case "-"
                        toReturn = toReturn.Add(New
TimeSpan(Int32.Parse(offset(0)), Int32.Parse(offset(1)), 0))
                End Select

                Return toReturn '.ToLocalTime() 'we treat all dates in feeds
as if they are local time (later)

            Catch iex As IndexOutOfRangeException

                Throw New
FormatException("RES_ExceptionRFC2822InvalidTimezoneFormatMessage")
            End Try

        End Function

    End Class
End Namespace


--
Sincerely,

S. Justin Gengo, MCP
Web Developer / Programmer

www.aboutfortunate.com

"Out of chaos comes order."
                            Nietzsche
Show quote
"Milsnips" <milsn***@hotmail.com> wrote in message
news:e8qlHqGGGHA.3856@TK2MSFTNGP12.phx.gbl...
> hi there,
>
> i am trying to get some feeds into my site, but am having problems with
> the converting the date format of "pubDate" into a datetime variable:
>
> <pubDate>Wed, 28 Sep 2005 08:00:00 UT</pubDate>
>
> It doesnt seem to like it? Any help appreciated
>
> thanks,
> Paul
>

AddThis Social Bookmark Button