Top / プログラミングテクニック / 11.IsDate関数(使うな!)

エラーにしたいのにエラーにならない

VB が標準で提供している IsDate 関数。 これは、日付が妥当かどうかチェックする関数なのですが、思わぬ落とし穴があります。

評価する値IsDate関数の戻り値VBの認識
2000/4/13True2000年04月13日
4/13/2000True2000年04月13日
13/4/2000True2000年04月13日

上の表のように、日本で使われる書式では、エラーになってしまうはずのものまで、True になってしまいます。
きちんと自分で関数を作って、チェックしましょう。

   Public Function blnIsDate(strDestDate As String) As Boolean
       Dim strYear     As String
       Dim strMonth    As String
       Dim strDay      As String
       Dim pYear       As Long
       Dim pMonth      As Long
       Dim pDay        As Long
       Dim pDayMax     As Long
       Dim i           As Long
       Dim lngCount    As Long
       Dim pos(1 To 2) As Long

       blnIsDate = False
       For i = 1 To Len(strDestDate)
           If Mid(strDestDate, i, 1) = "/" Then
               lngCount = lngCount + 1
               If lngCount > 2 Then Exit Function
               pos(lngCount) = i
           End If
       Next
       If lngCount <> 2 Then Exit Function

       strYear = Left(strDestDate, pos(1) - 1)
       strMonth = Mid(strDestDate, pos(1) + 1, pos(2) - pos(1) - 1)
       strDay = Mid(strDestDate, pos(2) + 1)

       If Not chkNumeric(strYear) Then Exit Function
       If Not chkNumeric(strMonth) Then Exit Function
       If Not chkNumeric(strDay) Then Exit Function

       pYear = CLng(strYear)
       pMonth = CLng(strMonth)
       pDay = CLng(strDay)

       Select Case pMonth
         Case 1, 3, 5, 7, 8, 10, 12
              pDayMax = 31
         Case 4, 6, 9, 11
              pDayMax = 30
         Case 2
              pDayMax = 28 - ((pYear Mod 400) = 0) _
                    + ((pYear Mod 100) = 0) - ((pYear Mod 4) = 0)
         Case Else
              Exit Function
       End Select

       If (pDay >= 1) And (pDay <= pDayMax) Then blnIsDate = True

   End Function

   Private Function chkNumeric(chkStr As String) As Boolean
   Dim i As Integer
       chkNumeric = True
       For i = 1 To Len(chkStr)
         If InStr("0123456789", Mid(chkStr, i, 1)) Then
         Else
            chkNumeric = False
            Exit For
         End If
       Next
   End Function

こんなのもOKだったりします。

? IsDate("0A")
True



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2009-10-25 (日) 23:55:56 (2800d)