here is what I use… trys PARSEDATE … if that fails it begins “guessing”
Hopefully I included all the support routines… if not, let me know and I will post them
FUNCTION IsValidDate(byref in_date as string,fmt as integer,include_zero_day as boolean=false) as boolean
Dim theDate As New date
Dim i As Integer
Dim m As String
Dim x As Integer
Dim y As Integer
Dim t As String
Dim ok As Boolean
Dim mth As Integer
Dim dy As Integer
Dim yr As Integer
Dim s As String
Dim v(-1) As String
If fmt<0 Then fmt=optionDATEFMT
s=Trim(in_date)
If s<>"" Then
ok=ParseDate(s,thedate)
If ok And theDate.year<100 Then
yr=FIX_YEAR(Val(Right(theDate.Shortdate,4)))
s=Left(theDate.ShortDate,6)+Format(yr,"0000")
ok=ParseDate(s,theDate)
End If
//
If Not ok Then ' lets force things a bit
t=cleanup_slashes(s)
For i=1 To 12
m=Mid(MonthNames,(i-1)*3+1,3)
x=InStr(t,m)
If x>0 Then
// if full month name .. blank out all but 1st 3 char.
dy=0
For y=x+3 To t.Len
If InStr("/0123456789",Mid(t,y,1))>0 Then
dy=y
Exit For
End If
Next y
If dy>x+3 Then t=Left(t,x+3)+Mid(t,dy)
//
If x>1 Then
t=cleanup_slashes(Left(t,x-1)+"/"+Mid(t,x,3)+"/"+Mid(t,x+3))
x=InStr(t,m)
y=InStr(x,t,"/")
mth=i
yr=0
dy=Val(ReplaceAll(Left(t,x-1),"/",""))
If y>0 Then
yr=Val(ReplaceAll(Mid(t,y),"/",""))
End If
If dy>31 Or yr=0 Then
y=dy
dy=yr
yr=y
End If
t=Str(mth)+"/"
If dy>0 Then t=t+Str(dy)+"/"
t=t+Str(fix_year(yr))
Else
t=cleanup_slashes(Str(i)+"/"+Mid(t,4))
x=5
End If
Exit For
End If
Next i
//
For i=1 To Len(t)
m=Mid(t,i,1)
If Not IsNumeric(m) And m<>"/" Then t=ReplaceAll(t,m,"/")
Next i
t=cleanup_slashes(t)
v=Split(t,"/")
If v.ubound>0 Then
For i=v.Ubound DownTo 0
If v(i)="" Then v.remove i
Next i
'
' if v(0)>31 then assume that YEAR was put first
If Val(v(0))>31 Then
v.append v(0)
v.remove 0
t=v(0)+"/"+v(1)
If v.Ubound=2 Then t=t+"/"+v(2)
End If
//
yr=fix_year(Val(v(v.Ubound)))
v(v.Ubound)=Str(yr)
If v.ubound=2 And Val(v(1))=0 Then v.remove 1 ' 00 was day value
If v.Ubound=1 Then 'missing day
t=v(0)+"/1/"+v(1)
End If
ok=ParseDate(t,thedate)
End If
End If
//
If ok Then
thedate.year=FIX_YEAR(thedate.year)
s=formatdate(theDate,fmt,(v.ubound=1))
End If
End If
If ok Then in_date=s
Return ok
FUNCTION FIX_YEAR(yr as integer) as integer
If yr<100 Then
If yr<50 Then
yr=2000+yr
Else
yr=1900+yr
End If
End If
Return yr
END FUNCTION
FUNCTION cleanup_slashes(t as string,include_colon as boolean=true) as string
Dim s As String=" -.\\:,;+"
Dim i As Integer
For i=1 To Len(s)
If (Mid(s,i,1)=":" Or Mid(s,i,1)=" ") And Not include_colon Then Continue
t=ReplaceAll(t,Mid(s,i,1),"/")
Next i
While InStr(t,"//")>0
t=ReplaceAll(t,"//","/")
Wend
While Right(t,1)="/"
t=Left(t,Len(t)-1)
If t="" Then Exit While
Wend
If Right(t,2)="/a" Or Right(t,2)="/p" Then t=t+"m"
If Right(t,3)="/am" Or Right(t,3)="/pm" Then t=Left(t,Len(t)-3)+Right(t,2)
Return t
END FUNCTION
FUNCTION format_date(dt as date,fmt as integer,force_zero_day as boolean=false) as string
Dim xday As Integer
xday=dt.day
If force_zero_day Then xday=0
Return INPUT_DATE(Format(dt.Year,"0000")+Format(dt.Month,"00")+Format(xDay,"00"),fmt)
//return Format(dt.Month,"00")+"/"+Format(dt.Day,"00")+"/"+Format(dt.Year,"0000")
END FUNCTION