A better CDate for VB6

后端 未结 8 715
悲哀的现实
悲哀的现实 2020-12-21 05:43

We have a a VB6 app (in a COM component) which uses CDate() to take a string and cast it to a Date, for storing in a database.

Depending on if we want the applicatio

8条回答
  •  萌比男神i
    2020-12-21 06:13

    This should be close, though it hardcodes the delimiter as "/" and windows YY years at 50:

    Private Function ParseDate(ByVal DateString As String, _
                               ByVal DatePattern As String) As Date
        'DateString:  i/j/k formatting.
        'DatePattern: i/j/k formatting, each to be:
        '               M or MM for month position.
        '               D or DD for day position.
        '               YY or YYYY for year position, if YY
        '                 then century windowed at 50.
        Dim strStringParts() As String
        Dim strPatternParts() As String
        Dim intPart As Integer, intScore As Integer
        Dim intMonth As Integer, intDay As Integer, intYear As Integer
        Const DELIM As String = "/"
        Const YYWINDOW As Integer = 50
    
        strStringParts = Split(DateString, DELIM)
        strPatternParts = Split(UCase$(DatePattern), DELIM)
        For intPart = 0 To UBound(strStringParts)
            If intPart > UBound(strPatternParts) Then
                Err.Raise 5, "ParseDate"
            End If
            Select Case strPatternParts(intPart)
                Case "M", "MM"
                    intMonth = CInt(strStringParts(intPart))
                    intScore = intScore Or &H1
                Case "D", "DD"
                    intDay = CInt(strStringParts(intPart))
                    intScore = intScore Or &H2
                Case "YY"
                    intYear = CInt(strStringParts(intPart))
                    If 0 > intYear Or intYear > 99 Then
                        Err.Raise 5, "ParseDate"
                    End If
                    intYear = intYear + IIf(intYear < YYWINDOW, 2000, 1900)
                    intScore = intScore Or &H4
                Case "YYYY"
                    intYear = CInt(strStringParts(intPart))
                    If 100 > intYear Or intYear > 9999 Then
                        Err.Raise 5, "ParseDate"
                    End If
                    intScore = intScore Or &H4
                Case Else
                    Err.Raise 5, "ParseDate"
            End Select
        Next
        If intScore = &H7 Then
            ParseDate = DateSerial(intYear, intMonth, intDay)
        Else
            Err.Raise 5, "ParseDate"
        End If
    End Function
    

    Validation may not be perfect, but it ought to be close. It throws "Invalid procedure call or argument (Error 5)" on bad inputs.

提交回复
热议问题