Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Silly VBScript IsDate problem

197 views
Skip to first unread message

B. Chernick

unread,
Nov 27, 2007, 5:05:02 PM11/27/07
to
I haven't used VBScript in a couple of years. I have a textbox and a custom
validator on the screen. The validator calls a vbscript function
ValidateDate which uses IsDate to validate incoming date strings. It will
catch gross errors like letters but it's passing date strings like
'13/12/2007'. I don't remember having this problem before. My machine's
regional setting is English (US). Here's the function.

<script language=vbscript type="text/vbscript" >
Function ValidateDate(sender, args)
if not IsDate(args.Value) and not trim(args.Value) = "" then
args.IsValid = False
Else
args.IsValid = True
End if
End function
</script>


mr_unreliable

unread,
Nov 27, 2007, 6:00:27 PM11/27/07
to
hi B Chernick,

On my (ancient) "English (US)" system:

MsgBox(IsDate("13/12/2007")) returns TRUE

MsgBox(IsDate(#13/12/2007#)) returns TRUE

MsgBox(CDate("13/12/2007")) returns "12/13/07"

MsgBox(CDate(#13/12/2007#)) returns "12/13/07"

go figure.

The documentation says that IsDate returns true if "an
expression can be converted to a date". And by golly
it CAN BE converted to a date. Whether or not that is
a valid conversion, is open to question. Nevertheless,
microsoft is able to convert it...

cheers, jw

B. Chernick

unread,
Nov 28, 2007, 7:29:01 AM11/28/07
to
Strange. I have a memory of testing IsDate on my former job and it seemed to
behave far better. (We used vbscript rather than javascript for most date
validation work because it seemed easier.) But then that other project had
very specific regionalization.

mr_unreliable

unread,
Nov 28, 2007, 12:14:30 PM11/28/07
to
If you really, really, really want a more valid date check,
you may have to resort to a "do-it-yourself" approach.

You could use a "regular expression" test, to see if the date
was formatted properly. And then, if you wanted an exhaustive
check, split the string and individually test for valid month
and day (and year) expressions.

btw, I ran the same test on vb(5), in hopes of finding a
better "IsDate", and got the same result as vbs.

cheers, jw

p.s. if you want to code up a more rigorous "IsDate" function,
then here is one from the AutoIt language "include" file,
written by Jeremy Landes. Granted, autoit code is not vbs
code, but with a little imagination (or perhaps reference to
the autoit help file) you should be able to follow the logic
and convert it to vbs. (Beware the word-wrap).

--- <autoit code> ---
; #FUNCTION#
====================================================================================================================
; Name...........: _DateIsValid
; Description ...: Checks the given date to determine if it is a valid date.
; Syntax.........: _DateIsValid($sDate)
; Parameters ....: $sDate - The date to be checked.
; Return values .: Success - Returns 1.
; Failure - Returns 0 if the specified date is not valid.
; Author ........: Jeremy Landes <jlandes at landeserve dot com>
; Modified.......:
; Remarks .......: This function takes a date input in one of the
following formats:
; "yyyy/mm/dd[ hh:mm[:ss]]" or "yyyy/mm/dd[Thh:mm[:ss]]"
; "yyyy-mm-dd[ hh:mm[:ss]]" or "yyyy-mm-dd[Thh:mm[:ss]]"
; "yyyy.mm.dd[ hh:mm[:ss]]" or "yyyy.mm.dd[Thh:mm[:ss]]"
; Related .......:
; Link ..........;
; Example .......; Yes
;
===============================================================================================================================
Func _DateIsValid($sDate)
Local $asDatePart[4]
Local $asTimePart[4]
Local $iNumDays
Local $sDateTime
$iNumDays = "31,28,31,30,31,30,31,31,30,31,30,31"
$iNumDays = StringSplit($iNumDays, ",")
; split the Date and Time portion
$sDateTime = StringSplit($sDate, " T")
; split the date portion
If $sDateTime[0] > 0 Then $asDatePart = StringSplit($sDateTime[1], "/-.")
; Ensure the date contains 3 sections YYYY MM DD
If UBound($asDatePart) <> 4 Then Return (0)
If $asDatePart[0] <> 3 Then Return (0)
; verify valid input date values
; Make sure the Date parts contains numeric
If Not StringIsInt($asDatePart[1]) Then Return (0)
If Not StringIsInt($asDatePart[2]) Then Return (0)
If Not StringIsInt($asDatePart[3]) Then Return (0)
$asDatePart[1] = Number($asDatePart[1])
$asDatePart[2] = Number($asDatePart[2])
$asDatePart[3] = Number($asDatePart[3])
; check if all contain valid values
If _DateIsLeapYear($asDatePart[1]) Then $iNumDays[2] = 29
If $asDatePart[1] < 1000 Or $asDatePart[1] > 2999 Then Return (0)
If $asDatePart[2] < 1 Or $asDatePart[2] > 12 Then Return (0)
If $asDatePart[3] < 1 Or $asDatePart[3] > $iNumDays[$asDatePart[2]]
Then Return (0)
; split the Time portion
If $sDateTime[0] > 1 Then
$asTimePart = StringSplit($sDateTime[2], ":")
If UBound($asTimePart) < 4 Then ReDim $asTimePart[4]
Else
Dim $asTimePart[4]
EndIf
; check Time portion
If $asTimePart[0] < 1 Then Return (1) ; No time specified
so date must be correct
If $asTimePart[0] < 2 Then Return (0) ; need at least HH:MM
when something is specified
If $asTimePart[0] = 2 Then $asTimePart[3] = "00" ; init SS when only
HH:MM is specified
; Make sure the Time parts contains numeric
If Not StringIsInt($asTimePart[1]) Then Return (0)
If Not StringIsInt($asTimePart[2]) Then Return (0)
If Not StringIsInt($asTimePart[3]) Then Return (0)
; check if all contain valid values
$asTimePart[1] = Number($asTimePart[1])
$asTimePart[2] = Number($asTimePart[2])
$asTimePart[3] = Number($asTimePart[3])
If $asTimePart[1] < 0 Or $asTimePart[1] > 23 Then Return (0)
If $asTimePart[2] < 0 Or $asTimePart[2] > 59 Then Return (0)
If $asTimePart[3] < 0 Or $asTimePart[3] > 59 Then Return (0)
; we got here so date/time must be good
Return (1)
EndFunc ;==>_DateIsValid
--- </autoit code> ---

Dr J R Stockton

unread,
Nov 28, 2007, 10:22:53 AM11/28/07
to
In microsoft.public.scripting.vbscript message <E665A43E-5A29-4730-AE5B-
0D2B31...@microsoft.com>, Tue, 27 Nov 2007 14:05:02, B. Chernick
<BChe...@discussions.microsoft.com> posted:

>I haven't used VBScript in a couple of years. I have a textbox and a custom
>validator on the screen. The validator calls a vbscript function
>ValidateDate which uses IsDate to validate incoming date strings. It will
>catch gross errors like letters but it's passing date strings like
>'13/12/2007'.

It will accept "23p" too. And "13/12/2007" is a perfectly valid date;
are you foreign?

> I don't remember having this problem before. My machine's
>regional setting is English (US). Here's the function.
>
><script language=vbscript type="text/vbscript" >
> Function ValidateDate(sender, args)
> if not IsDate(args.Value) and not trim(args.Value) = "" then
> args.IsValid = False
> Else
> args.IsValid = True
> End if
> End function
> </script>

(A) You surely do not need that complex IF statement :
args.IsValid = IsDate(args.Value) or trim(args.Value) = ""
but do you really want that trim test?

(B) Read <URL:http://www.merlyn.demon.co.uk/vb-dates.htm> ff.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.

Dr J R Stockton

unread,
Nov 28, 2007, 5:05:34 PM11/28/07
to
In microsoft.public.scripting.vbscript message <#CHqtFeMIHA.5860@TK2MSFT
NGP04.phx.gbl>, Wed, 28 Nov 2007 12:14:30, mr_unreliable <kindlyReplyToN
ewsg...@notmail.com> posted:

>If you really, really, really want a more valid date check,
>you may have to resort to a "do-it-yourself" approach.

Yes, but it's easy and brief, if you know how.

>You could use a "regular expression" test, to see if the date
>was formatted properly. And then, if you wanted an exhaustive
>check, split the string

So far, so good.

>and individually test for valid month
>and day (and year) expressions.

But no further.


>p.s. if you want to code up a more rigorous "IsDate" function,
>then here is one from the AutoIt language "include" file,

> ...

> $iNumDays = "31,28,31,30,31,30,31,31,30,31,30,31"

Not needed in VBS.

> If _DateIsLeapYear($asDatePart[1]) Then $iNumDays[2] = 29

Not needed in VBS.

> If $asDatePart[1] < 1000 Or $asDatePart[1] > 2999 Then Return (0)

Restrictive.


And VBS can do it much more briefly, if used intelligently; see via sig.


Of course, a really good date-and-time validator would warn if the time
was in the missing Spring hour or the duplicated Autumn hour. That's
less easy, especially if the data is non-local.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm

Dates - miscdate.htm moredate.htm vb-dates.htm pas-time.htm critdate.htm etc.

0 new messages