Is_Date() function for strings in mutiple possible formats
Moderator: Rathinagiri
-
HGAutomator
- Posts: 202
- Joined: Thu Jul 16, 2020 5:42 pm
- DBs Used: DBF
Is_Date() function for strings in mutiple possible formats
Is there an IS_Date() function, other than the standard one which determines if a variable is a date object?
I'm looking for something that can intelligently determine that a string could be a date, by analyzing whether it fits an mm/dd/yyyy or yyymmdd or other potential date formats.
In a sense, I'm really trying to determine if a string can NOT be a date.
I'm looking for something that can intelligently determine that a string could be a date, by analyzing whether it fits an mm/dd/yyyy or yyymmdd or other potential date formats.
In a sense, I'm really trying to determine if a string can NOT be a date.
- Claudio Ricardo
- Posts: 367
- Joined: Tue Oct 27, 2020 3:38 am
- DBs Used: DBF, MySQL, MariaDB
- Location: Bs. As. - Argentina
Re: Is_Date() function for strings in mutiple possible formats
Hi... Maybe:
Function Is_Date (xParam)
Return Iif ( ValType ( xParam ) == "D", .T., .F.)
Function Is_Date (xParam)
Return Iif ( ValType ( xParam ) == "D", .T., .F.)
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
WhatsApp / Telegram: +54 911-63016162
-
HGAutomator
- Posts: 202
- Joined: Thu Jul 16, 2020 5:42 pm
- DBs Used: DBF
Re: Is_Date() function for strings in mutiple possible formats
Hi,
Thanks Claudio, but we're not looking at date variables. We're looking at strings that might be convertible to a date variable. Or rather, I'm looking at strings that can't possibly be converted to a date variable.
I need to determine whether a variable might contain a string date, or whether is obviously cannot. So the string "01012010" might refer to a date in the forms mmddyyyy or ddmmyyyy ; but the string "helloworld" or "31201313" cannot be dates.
I'm pretty sure I've seen something like this before, althought it might not have been Harbour.
Thanks Claudio, but we're not looking at date variables. We're looking at strings that might be convertible to a date variable. Or rather, I'm looking at strings that can't possibly be converted to a date variable.
I need to determine whether a variable might contain a string date, or whether is obviously cannot. So the string "01012010" might refer to a date in the forms mmddyyyy or ddmmyyyy ; but the string "helloworld" or "31201313" cannot be dates.
I'm pretty sure I've seen something like this before, althought it might not have been Harbour.
Claudio Ricardo wrote: ↑Thu Jul 08, 2021 7:24 pm Hi... Maybe:
Function Is_Date (xParam)
Return Iif ( ValType ( xParam ) == "D", .T., .F.)
Re: Is_Date() function for strings in mutiple possible formats
Hola,
Prueba con :
dVar := "25-15-2021"
IF EMPTY( CTOD(dVar))
// Fecha Inválido
ELSE
// Fecha válida
ENDF
Ayuda :
CTOD()
Convert a date string to a date value
------------------------------------------------------------------------------
Syntax
CTOD(<cDate>) --> dDate
Arguments
<cDate> is a character string consisting of numbers representing the
month, day, and year separated by any character other than a number.
The month, day, and year digits must be specified in accordance with the
SET DATE format. If the century digits are not specified, the century
is determined by the rules of SET EPOCH.
Returns
CTOD() returns a date value. If <cDate> is not a valid date, CTOD()
returns an empty date.
Prueba con :
dVar := "25-15-2021"
IF EMPTY( CTOD(dVar))
// Fecha Inválido
ELSE
// Fecha válida
ENDF
Ayuda :
CTOD()
Convert a date string to a date value
------------------------------------------------------------------------------
Syntax
CTOD(<cDate>) --> dDate
Arguments
<cDate> is a character string consisting of numbers representing the
month, day, and year separated by any character other than a number.
The month, day, and year digits must be specified in accordance with the
SET DATE format. If the century digits are not specified, the century
is determined by the rules of SET EPOCH.
Returns
CTOD() returns a date value. If <cDate> is not a valid date, CTOD()
returns an empty date.
-
HGAutomator
- Posts: 202
- Joined: Thu Jul 16, 2020 5:42 pm
- DBs Used: DBF
Re: Is_Date() function for strings in mutiple possible formats
Thanks I'm familar with the date functions, but they all assume that the date string is in a specific format. I'm looking for a function that covers all possible formats. Also, it doesn't need to convert the string to a date ; it just needs to determine that it's IMPOSSIBLE to convert the string to a date.
So it would have to cover all possible date formats, regardless of the state of SET DATE or EPOCH.
Anyway, I'm searching through some of my old code, non-clipper/harbour. I'm nearly certain that this was done, somewhere.
If not, I'll build it from scratch.
Regards,
So it would have to cover all possible date formats, regardless of the state of SET DATE or EPOCH.
Anyway, I'm searching through some of my old code, non-clipper/harbour. I'm nearly certain that this was done, somewhere.
If not, I'll build it from scratch.
Regards,
wistong wrote: ↑Thu Jul 08, 2021 8:01 pm Hola,
Prueba con :
dVar := "25-15-2021"
IF EMPTY( CTOD(dVar))
// Fecha Inválido
ELSE
// Fecha válida
ENDF
Ayuda :
CTOD()
Convert a date string to a date value
------------------------------------------------------------------------------
Syntax
CTOD(<cDate>) --> dDate
Arguments
<cDate> is a character string consisting of numbers representing the
month, day, and year separated by any character other than a number.
The month, day, and year digits must be specified in accordance with the
SET DATE format. If the century digits are not specified, the century
is determined by the rules of SET EPOCH.
Returns
CTOD() returns a date value. If <cDate> is not a valid date, CTOD()
returns an empty date.
- danielmaximiliano
- Posts: 2763
- Joined: Fri Apr 09, 2010 4:53 pm
- DBs Used: DBF
- Location: Argentina
- Contact:
Re: Is_Date() function for strings in mutiple possible formats
se deberia usar expresiones regulares para saber si una fecha es correcta en diferenes formatos.
ej
1-4-94
01/04/94
01-04-1994
etc... http://www.hmgforum.com/viewtopic.php?t=3382
ej
1-4-94
01/04/94
01-04-1994
etc... http://www.hmgforum.com/viewtopic.php?t=3382
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*
Saludos / Regards
DaNiElMaXiMiLiAnO
Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
Telegram invitation https://t.me/HMGWorkspace
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*
Saludos / Regards
DaNiElMaXiMiLiAnO
Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
Telegram invitation https://t.me/HMGWorkspace
- Claudio Ricardo
- Posts: 367
- Joined: Tue Oct 27, 2020 3:38 am
- DBs Used: DBF, MySQL, MariaDB
- Location: Bs. As. - Argentina
Re: Is_Date() function for strings in mutiple possible formats
Hola...
Se complica aún más, ya que necesita que sea independiente del Set Date... Nosotros usamos French o German "ddmmyyyy"
pero si lo ingresan como USA "mmddyyyy" o Japan "yyyymmdd" y sin Set Century On es "yy" (año en dos digitos)
Por ejemplo 101112 puede ser valido como 10 de noviembre de 2012 o 11 de octubre de 2012 o 12 de noviembre de 2010 respectivamente
Se complica aún más, ya que necesita que sea independiente del Set Date... Nosotros usamos French o German "ddmmyyyy"
pero si lo ingresan como USA "mmddyyyy" o Japan "yyyymmdd" y sin Set Century On es "yy" (año en dos digitos)
Por ejemplo 101112 puede ser valido como 10 de noviembre de 2012 o 11 de octubre de 2012 o 12 de noviembre de 2010 respectivamente
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
WhatsApp / Telegram: +54 911-63016162
-
HGAutomator
- Posts: 202
- Joined: Thu Jul 16, 2020 5:42 pm
- DBs Used: DBF
Re: Is_Date() function for strings in mutiple possible formats
Thanks Claudio,
For the file that we're analyzing, we don't have to worry about formats like
November 12, 2010
It'll be just digits ; or digits & slashes ; or digits & dashes.
For the file that we're analyzing, we don't have to worry about formats like
November 12, 2010
It'll be just digits ; or digits & slashes ; or digits & dashes.
Claudio Ricardo wrote: ↑Fri Jul 09, 2021 7:04 am Hola...
Se complica aún más, ya que necesita que sea independiente del Set Date... Nosotros usamos French o German "ddmmyyyy"
pero si lo ingresan como USA "mmddyyyy" o Japan "yyyymmdd" y sin Set Century On es "yy" (año en dos digitos)
Por ejemplo 101112 puede ser valido como 10 de noviembre de 2012 o 11 de octubre de 2012 o 12 de noviembre de 2010 respectivamente![]()
Re: Is_Date() function for strings in mutiple possible formats
I used to need something similar that you ask. Maybe it will be helpful.
Code: Select all
#include <hmg.ch>
PROCEDURE Main()
msgdebug (IsStringValidDate( "" ) ) //.F.
msgdebug (IsStringValidDate( "30-02-1990" )) //.F.
msgdebug (IsStringValidDate( "01/02/2011" ), CheckStringValidDate( "01/02/2011" )) //.T.
msgdebug (IsStringValidDate( "2001\02\20" )) //.T.
msgdebug (IsStringValidDate( "12.20.2011" )) //.T.
msgdebug (IsStringValidDate( "12-20-11" )) //.T.
msgdebug (IsStringValidDate( "12.40.2011" )) //.F.
msgdebug (IsStringValidDate( "12.2011.20" )) //.T.
msgdebug (IsStringValidDate( "12402011" ), CheckStringValidDate( "12402011" ) ) //.T. => 1240.20.11, 12.11.4020, 11.12.4020
msgdebug (IsStringValidDate( "12402011", hb_CtoD( "01/01/1990" , "dd/mm/yyyy" ) /* FromDate */ , hb_CtoD( "31/12/2050" , "dd/mm/yyyy" ) /* ToDate */ )) //.F.
msgdebug (IsStringValidDate( "310210" ), CheckStringValidDate( "310210" ) ) //.T. => 31.10.1902, 1931.02.10, 1931.10.02
msgdebug (IsStringValidDate( "310210", hb_CtoD( "01/01/1990" , "dd/mm/yyyy" ) /* FromDate */ , hb_CtoD( "31/12/2050" , "dd/mm/yyyy" ) /* ToDate */ )) //.F.
msgdebug (IsStringValidDate( "12@40@2011" )) //.F.
msgdebug (IsStringValidDate( "12x40x2011" )) //.F.
msgdebug (IsStringValidDate( 1111 )) //.F.
msgdebug (IsStringValidDate( .F. )) //.F.
msgdebug (IsStringValidDate( )) //.F.
RETURN
*************************************************************************
Function IsStringValidDate( cDate, dRangeFrom, dRangeTo )
Local lValidDate := Len ( CheckStringValidDate( cDate, dRangeFrom, dRangeTo ) ) > 0
RETURN lValidDate
*************************************************************************
Function CheckStringValidDate( cDate, dRangeFrom, dRangeTo )
Local cSep:=".-/\ ", cDateCheck
Local i, j, nInsPos
Local isSep := .F.
Local aDateFormats:={ "dd/mm/yyyy", "dd/mm/yy",;
"mm/dd/yyyy", "mm/dd/yy", ;
"yyyy/mm/dd", "yy/mm/dd", ;
"yyyy/dd/mm", "yy/dd/mm", ;
"mm/yyyy/dd", "mm/yy/dd", ;
"dd/yyyy/mm", "dd/yy/mm" }, ;
aTokens, aDates :={}
Local dDate
Default cDate := ""
Default dRangeFrom := CToD( "" ), dRangeTo := hb_CtoD( "31/12/9999" , "dd/mm/yyyy" )
IF !hb_isChar ( cDate )
Return aDates
ENDIF
FOR i:=1 TO Len ( cDate )
IF Substr( cDate, i, 1 ) $ cSep
isSep := .T.
ELSEIF !IsDigit( Substr( cDate, i, 1 ) )
Return aDates
ENDIF
NEXT i
FOR i:=1 TO Len ( aDateFormats )
IF !isSep
aTokens := hb_Atokens ( aDateFormats [i], "/" )
cDateCheck := cDate
nInsPos := 0
FOR j := 1 TO Len ( aTokens ) - 1
nInsPos += Len( aTokens [j]) + 1
cDateCheck := Stuff(cDateCheck, nInsPos, 0, "/")
NEXT j
ELSE
cDateCheck := cDate
ENDIF
dDate := hb_CtoD( cDateCheck , aDateFormats [i])
IF !EMPTY( dDate ) .AND. dDate >= dRangeFrom .AND. dDate <= dRangeTo
IF ASCAN ( aDates, dDate ) = 0
AADD ( aDates, dDate )
ENDIF
ENDIF
NEXT i
RETURN aDates
-
HGAutomator
- Posts: 202
- Joined: Thu Jul 16, 2020 5:42 pm
- DBs Used: DBF
Re: Is_Date() function for strings in mutiple possible formats
Perfect, edk. Thanks.
edk wrote: ↑Fri Jul 09, 2021 10:37 am I used to need something similar that you ask. Maybe it will be helpful.Code: Select all
#include <hmg.ch> PROCEDURE Main() msgdebug (IsStringValidDate( "" ) ) //.F. msgdebug (IsStringValidDate( "30-02-1990" )) //.F. msgdebug (IsStringValidDate( "01/02/2011" ), CheckStringValidDate( "01/02/2011" )) //.T. msgdebug (IsStringValidDate( "2001\02\20" )) //.T. msgdebug (IsStringValidDate( "12.20.2011" )) //.T. msgdebug (IsStringValidDate( "12-20-11" )) //.T. msgdebug (IsStringValidDate( "12.40.2011" )) //.F. msgdebug (IsStringValidDate( "12.2011.20" )) //.T. msgdebug (IsStringValidDate( "12402011" ), CheckStringValidDate( "12402011" ) ) //.T. => 1240.20.11, 12.11.4020, 11.12.4020 msgdebug (IsStringValidDate( "12402011", hb_CtoD( "01/01/1990" , "dd/mm/yyyy" ) /* FromDate */ , hb_CtoD( "31/12/2050" , "dd/mm/yyyy" ) /* ToDate */ )) //.F. msgdebug (IsStringValidDate( "310210" ), CheckStringValidDate( "310210" ) ) //.T. => 31.10.1902, 1931.02.10, 1931.10.02 msgdebug (IsStringValidDate( "310210", hb_CtoD( "01/01/1990" , "dd/mm/yyyy" ) /* FromDate */ , hb_CtoD( "31/12/2050" , "dd/mm/yyyy" ) /* ToDate */ )) //.F. msgdebug (IsStringValidDate( "12@40@2011" )) //.F. msgdebug (IsStringValidDate( "12x40x2011" )) //.F. msgdebug (IsStringValidDate( 1111 )) //.F. msgdebug (IsStringValidDate( .F. )) //.F. msgdebug (IsStringValidDate( )) //.F. RETURN ************************************************************************* Function IsStringValidDate( cDate, dRangeFrom, dRangeTo ) Local lValidDate := Len ( CheckStringValidDate( cDate, dRangeFrom, dRangeTo ) ) > 0 RETURN lValidDate ************************************************************************* Function CheckStringValidDate( cDate, dRangeFrom, dRangeTo ) Local cSep:=".-/\ ", cDateCheck Local i, j, nInsPos Local isSep := .F. Local aDateFormats:={ "dd/mm/yyyy", "dd/mm/yy",; "mm/dd/yyyy", "mm/dd/yy", ; "yyyy/mm/dd", "yy/mm/dd", ; "yyyy/dd/mm", "yy/dd/mm", ; "mm/yyyy/dd", "mm/yy/dd", ; "dd/yyyy/mm", "dd/yy/mm" }, ; aTokens, aDates :={} Local dDate Default cDate := "" Default dRangeFrom := CToD( "" ), dRangeTo := hb_CtoD( "31/12/9999" , "dd/mm/yyyy" ) IF !hb_isChar ( cDate ) Return aDates ENDIF FOR i:=1 TO Len ( cDate ) IF Substr( cDate, i, 1 ) $ cSep isSep := .T. ELSEIF !IsDigit( Substr( cDate, i, 1 ) ) Return aDates ENDIF NEXT i FOR i:=1 TO Len ( aDateFormats ) IF !isSep aTokens := hb_Atokens ( aDateFormats [i], "/" ) cDateCheck := cDate nInsPos := 0 FOR j := 1 TO Len ( aTokens ) - 1 nInsPos += Len( aTokens [j]) + 1 cDateCheck := Stuff(cDateCheck, nInsPos, 0, "/") NEXT j ELSE cDateCheck := cDate ENDIF dDate := hb_CtoD( cDateCheck , aDateFormats [i]) IF !EMPTY( dDate ) .AND. dDate >= dRangeFrom .AND. dDate <= dRangeTo IF ASCAN ( aDates, dDate ) = 0 AADD ( aDates, dDate ) ENDIF ENDIF NEXT i RETURN aDates