【问题标题】:VBA string with milliseconds to date迄今为止毫秒的 VBA 字符串
【发布时间】:2017-12-23 10:50:24
【问题描述】:

我有一个"yyyy-mm-dd hh:mm:ss.mmm" 形式的字符串(结尾是毫秒)

我想把它转换成一个数字,最好是Date,它会保留所有信息

我试过CDate(),例如。

Dim dateValue As Date
dateValue = CDate("2017-12-23 10:29:15.223")

但是得到一个类型不匹配的错误

【问题讨论】:

标签: excel vba datetime


【解决方案1】:

Date 类型保存自 December 30 1899 以来的天数,精度为一秒。虽然仍然可以通过将日期存储在货币类型中来保存毫秒,因为与日期/双精度相比,它可以保存 4 个额外的数字。

因此,另一种方法是将日期存储为 Currency 类型中的时间戳,表示自 December 30 1899 以来的秒数:

Public Function CDateEx(text As String) As Currency
    Dim parts() As String
    parts = Split(text, ".")
    CDateEx = CCur(CDate(parts(0)) * 86400) + CCur(parts(1) / 1000)
End Function

并将时间戳转换回字符串:

Public Function FormatDateEx(dt As Currency) As String
    FormatDateEx = Format(dt / 86400, "yyyy-mm-dd HH:mm:ss") & "." & ((dt - Fix(dt)) * 1000)
End Function

【讨论】:

  • 这是一个很好的解决方案,谢谢迈克尔。虽然我认为 FormatDateEx 有一个小错误。我相信您需要 FormatDateEx = Format( *Fix*(dt) /86400, ..... 尝试使用 FormatDateEx(CDateEx("15:59:58.921")) 进行测试。如果没有修复,秒数变为 59,而不是 58 (在 Excel 2016 64 位窗口中)。我没有彻底测试过,所以要小心。
【解决方案2】:

为什么不使用 DateAdd 将获取整秒后的最后 0.233 秒添加为日期值?

Dim Str As String, MS As String
Dim DateValue As Date
Dim L as Integer
Str = "2017-12-23 10:29:15.223"
For L = 1 to Len(Str)
    If Left(Right(Str, L), 1) = "." Then
        MS = "0" & Right(Str, L)
        Str = Left(Str, Len(Str) - L)
        Exit For
    End If
Next L
DateValue = CDate(Str)
If MS <> "" Then DateValue = DateAdd("S",MS,DateValue)

【讨论】:

  • 不幸的是,正如其他答案所强调的那样,问题在于 Date 数据类型;它不支持毫秒精度的数字。所以DateAdd 无效,因为日期的小数部分被截断。您可以在 DateAdd 之前和之后使用 debug.print DateValue 进行测试
【解决方案3】:

以下代码包含管理日期及其毫秒数可能需要的所有组件。

Private Sub ParseTime()

    Dim strTime As String
    Dim Sp() As String
    Dim Dt As Double

    strTime = "2017-12-23 10:29:15.221"
    Sp = Split(strTime, ".")
    strTime = Sp(0)

    Dt = CDbl(CDate(strTime))
    strTime = "yyyy-mm-dd hh:mm:ss"
    If UBound(Sp) Then
        Dt = Dt + CDbl(Sp(1)) * 1 / 24 / 60 / 60 / (10 ^ Len(Sp(1)))
        strTime = strTime & "." & CInt(Sp(1))
    End If
    Debug.Print Format(Dt, strTime)
End Sub

我不能说我对解决方案完全满意,因为打印只是隐含地等于日期值。但是,我发现以前有效的日期/时间格式,如“yyyy-mm-dd hh:mm:ss.000”,自 2007 年以来似乎不起作用。但是,应该有可能最终证明日期/Time 值等于我上面包含的格式掩码 cd 的呈现。

【讨论】:

    【解决方案4】:

    当小数部分向上取整时,Michael 的答案有错误(由 Jim 发现)。

    以下内容更正了错误(稍微修改了十分之一秒而不是毫秒,并使用参数化格式模式)。

    Public Function FormatDateEx(dt As Currency, formatPattern As String) As String
        Rem FormatDateEx = Format(dt / 86400, "yyyy-mm-dd HH:mm:ss") & "." & ((dt - Fix(dt)) * 1000)
        Dim decimalPart As Double
        decimalPart = Round(((dt - Fix(dt)) * 10), 0)
        If (decimalPart = 10) Then
            FormatDateEx = format(dt / 86400, formatPattern) & ".0"
        Else
            FormatDateEx = format(Fix(dt) / 86400, formatPattern) & "." & decimalPart
        End If
    End Function
    

    【讨论】:

      【解决方案5】:

      使用Left$函数修整小数点和毫秒:

      Dim dateValue As Date
      dateValue = CDate(Left$("2017-12-23 10:29:15.223", 19))
      

      【讨论】:

      • UpVoting 因为知道 Date 数据类型具有秒的分辨率,这也是正确的。
      猜你喜欢
      • 2011-04-18
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      相关资源
      最近更新 更多