Strtotime method for parsing an RFC2822 date/time string

// Method to parse an email date/time string (see RFC2822) and return the number of seconds since the epoch.
// Tried to make this robust by checking each bit exists before trying to examine it.
//
// The tmpDate at the end is made from the time/day values in the datestr, but with the *local*
// timezone, since that gives the correct adjustment back to the supplied offset.

//Note thet I use a dictionary for the months, (app.months) but this could be replaced with a select case.

Var  tmpDate As DateTime, d, parts(), tparts(), s as String, tz As TimeZone
Var  i, nxt, numparts, day, mon, year, hour, min, sec, offset As Integer

epochsecs = 0.0

d = datestr.trim ()

if  (d.Length=0)  then Return False

parts = d.split (" ")                                            // Split the string into components

for i = parts.LastIndex downto 0                                 // Any multiple spaces show up as
  if  (parts(i).Length>0)  then Continue                         // empty elements which can be
  parts.RemoveAt(i)                                              // removed.
next

numparts = parts.LastIndex
if  (numparts<3)  then Return False

nxt = if  (parts(0).Right(1)<>",", 0, 1)                         // Skip past a possible day-of-week

day = if  (numparts>=nxt, CLong (parts(nxt)), 0)                 // Validate the supposed day field and convert
if  (day<1 or day>31)  then Return False

nxt = nxt + 1
s   = if  (numparts>=nxt, parts(nxt), "none")
if  (app.months.HasKey (s)=False)  then Return False             // Convert the month
mon = app.months.value (s)

nxt  = nxt + 1
year = if  (numparts>=nxt, CLong (parts(nxt)), 0)
if  (year=0)  then Return False
if  (year<50)   then year = year + 2000
if  (year<100)  then year = year + 1900

nxt = nxt + 1
if  (numparts>=nxt)  then tparts = parts(nxt).split (":")        // Should split the time into bits
if  (tparts.LastIndex<1)  then Return False

hour = Clong (tparts(0))
min  = Clong (tparts(1))
sec  = if  (tparts.LastIndex=2, Clong (tparts(2)), 0)

if  (hour<0 or min<0 or sec<0 or hour>23 or min>59 or sec>59)  then Return False

nxt = nxt + 1
if  (numparts>=nxt)  then
  offset = toOffset (parts(nxt))
else
  offset = 0                                                     // Give up and assign UTC
end if

tz = new TimeZone (offset)

tmpDate   = new DateTime (year, mon, day, hour, min, sec, 0, tz)
epochSecs = tmpDate.SecondsFrom1970                              // Gives correct epochSecs.

Return True
4 Likes