Page 1 of 1

Parse dates like Tue, 14 May 2013 13:40:50 GMT

Posted: Tue May 14, 2013 6:36 pm
by PHP
Hi,

i know ParseDate() but how can i parse dates like Tue, 14 May 2013 13:40:50 GMT into 14.05.13 or something like this? Regular expressions?

Thanks,
PHP

Re: Parse dates like Tue, 14 May 2013 13:40:50 GMT

Posted: Tue May 14, 2013 7:24 pm
by Little John
A pretty simple way is to use StringField(), e.g. like in the following code. Other ways are also possible, of course.

Code: Select all

EnableExplicit

Structure MyTime
   weekday$
   day$
   month$
   year$
   hour$
   minute$
   second$
   zone$
EndStructure

Procedure ParseMyDate (myDate$, *parsed.MyTime)
   ; -- parse a given date
   ; in : myDate$: date in the form "Tue, 14 May 2013 13:40:50 GMT"
   ; out: *parsed: structured variable that contains the separate components of the date
   Protected rest$
   
   With *parsed
      \weekday$ = StringField(myDate$, 1, ",")
      rest$     = LTrim(StringField(myDate$, 2, ","))
      \day$     = StringField(rest$, 1, " ")
      \month$   = StringField(rest$, 2, " ")
      \year$    = StringField(rest$, 3, " ")
      \zone$    = StringField(rest$, 5, " ")
      rest$     = StringField(rest$, 4, " ")
      \hour$    = StringField(rest$, 1, ":")
      \minute$  = StringField(rest$, 2, ":")
      \second$  = StringField(rest$, 3, ":")
   EndWith
EndProcedure


;-- Demo
Define parsed.MyTime

ParseMyDate("Tue, 14 May 2013 13:40:50 GMT", parsed)

With parsed
   Debug "'" + \weekday$ + "'"
   Debug "'" + \day$ + "'"
   Debug "'" + \month$ + "'"
   Debug "'" + \year$ + "'"
   Debug "'" + \hour$ + "'"
   Debug "'" + \minute$ + "'"
   Debug "'" + \second$ + "'"
   Debug "'" + \zone$ + "'"
EndWith
After parsing the date, you can further process the separate components, using e.g. Val() etc.

Re: Parse dates like Tue, 14 May 2013 13:40:50 GMT

Posted: Tue May 14, 2013 8:13 pm
by PHP
Great solution John, thanks for this!

Re: Parse dates like Tue, 14 May 2013 13:40:50 GMT

Posted: Tue May 14, 2013 9:23 pm
by Little John
You are welcome!

A disadvantage of the above solution is, that it's not robust. I.e. if for instance some items are separated by 2 blanks instead of 1 blank, then it will fail.
Here is a pretty versatile and robust function, based on srod's Tokenizer. All credits go to srod, all mistakes are hand-crafted by me. :-)

Code: Select all

EnableExplicit

Procedure.i SplitString (line$, separator$, List token$())
   ; in : line$     : Text to be split
   ;      separator$: List of characters that act as delimiters
   ; out: token$()    : List of substrings which are delimited by
   ;                    any characters in separator$
   ;      return value: #False if 'line$' cannot be parsed, and
   ;                    #True otherwise
   Protected char$, left, right, length, result=#True
   
   left  = 1
   right = 1
   length = Len(line$)
   ClearList(token$())
   
   While right <= length   
      char$ = Mid(line$, right, 1)
      If FindString(separator$, char$, 1)
         If left < right
            AddElement(token$())
            token$() = Mid(line$, left, right-left)
            left = right
         Else         
            left  + 1
            right + 1
         EndIf
      ElseIf right = length
         right + 1
         AddElement(token$())
         token$() = Mid(line$, left, right-left)
      Else         
         right + 1
      EndIf
   Wend
   
   ProcedureReturn result
EndProcedure


;-- Demo
Macro SplitIt (_myDate_, _separators_)
   If SplitString(_myDate_, _separators_, token$())
      ForEach token$()
         Debug "'" + token$() + "'"
      Next
   Else
      Debug "Can't split '" + _myDate_ + "'."
   EndIf
   Debug "-------"
EndMacro


#MY_SEPARATORS = " ,:"
NewList token$()

; Splitting all the following strings will produce the same result:
SplitIt("Tue, 14 May 2013 13:40:50 GMT", #MY_SEPARATORS)
SplitIt("Tue 14  May   2013   13:40:50, GMT", #MY_SEPARATORS)
SplitIt("Tue   14 ,, May , 2013  13 : 40 : 50 GMT", #MY_SEPARATORS)

Re: Parse dates like Tue, 14 May 2013 13:40:50 GMT

Posted: Wed May 15, 2013 6:45 am
by Little John
This version uses a Regular Expression.

Code: Select all

EnableExplicit

Procedure.i ParseMyDate (myDate$, Array result$(1))
   Protected regEx.i, ret.i=0
   
   regEx = CreateRegularExpression(#PB_Any, "[^ ,:]+")
   If regEx
      ret = ExtractRegularExpression(regEx, myDate$, result$())
   Else
      result$(0) = RegularExpressionError()
   EndIf
   FreeRegularExpression(regEx)

   ProcedureReturn ret
EndProcedure


;-- Demo
Macro SplitIt (_myDate_)
   nbFound = ParseMyDate(_myDate_, result$())
   If nbFound
      For k = 0 To nbFound-1
         Debug "'" + result$(k) + "'"
      Next
   Else
      Debug "Can't split '" + _myDate_ + "'."
      Debug result$(0)
   EndIf
   Debug "-------"
EndMacro


Define.i nbFound, k
Dim result$(0)

; Splitting all the following strings will produce the same result:
SplitIt("Tue, 14 May 2013 13:40:50 GMT")
SplitIt("Tue 14  May   2013   13:40:50, GMT")
SplitIt("Tue   14 ,, May , 2013  13 : 40 : 50 GMT")