datetime - 一个更好的 VB6 CDate

标签 datetime vb6 casting regional

我们有一个 VB6 应用程序(在 COM 组件中),它使用 CDate() 获取字符串并将其转换为日期,以便存储在数据库中。

例如,根据我们希望应用程序以 dd/MM/yy 还是 MM/dd/yy 进行通话,我们必须更改 COM 应用程序的身份用户的区域设置。 (现在我们唯一的选择是 a nasty hack 。)

我们有一个用于格式化所有输出日期的日期格式字符串,并且假设日期

如果这是 .NET,我们将使用 DateTime.ParseExact 并且笑而不语。出于这个目的调用用 .NET 编写的 COM 对象是一种选择。是否有不同或更好的选择,包括围绕 Format 命令的一些黑魔法,或者根据格式字符串标记日期的长可重用函数等?

最佳答案

这应该很接近,尽管它将分隔符硬编码为“/”,并将 windows YY 年份硬编码为 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

验证可能并不完美,但应该接近。它在错误的输入上抛出“无效的过程调用或参数(错误 5)”。

关于datetime - 一个更好的 VB6 CDate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1059930/

相关文章:

android - 不明白 Android 中的 java.lang.ClassCastException 错误

c - 在C中强制转换为指针类型时会发生什么情况?

sql - 选择重叠的时间范围

vb6 - 如何在Windows XP中模拟慢速打印机?

java - 我无法理解 Java 8 中的一些 lambda 表达式

vb6 - SpreadsheetML 中的主题混淆

api - 将 URL 内容直接下载为字符串 (VB6),无需保存到磁盘

sql - 为什么 Azure Databricks 中的时间格式发生变化

c# - 如果列表有多个连续月份,则返回 true

php - 从 mysql 获取时间并以我们想要的任何格式回显它 - php