我有一个字符串,格式为"yyyy-mm-dd hh:mm:ss.mmm"
(其中结尾是毫秒)
我想将其转换为一个数字,最好是一个Date
对象,以保留所有信息。
我已经尝试使用CDate()
函数,例如:
Dim dateValue As Date
dateValue = CDate("2017-12-23 10:29:15.223")
但是会收到类型不匹配的错误。
我有一个字符串,格式为"yyyy-mm-dd hh:mm:ss.mmm"
(其中结尾是毫秒)
我想将其转换为一个数字,最好是一个Date
对象,以保留所有信息。
我已经尝试使用CDate()
函数,例如:
Dim dateValue As Date
dateValue = CDate("2017-12-23 10:29:15.223")
但是会收到类型不匹配的错误。
Date
类型以一秒的精度保存自1899年12月30日以来的天数。虽然仍然可以通过将日期存储在货币类型中来保存毫秒,因为它可以比Date/Double多保存4个额外数字。
因此,一种替代方案是将日期存储为时间戳,表示自1899年12月30日以来的秒数,并使用Currency
类型进行表示:
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
Left$
函数来截取小数点和毫秒部分:Dim dateValue As Date
dateValue = CDate(Left$("2017-12-23 10:29:15.223", 19))
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年以来似乎不起作用了。不过,应该可以通过上面所包含的格式掩码来证明日期/时间值等于其呈现。
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)
迈克尔的答案有一个错误(由吉姆发现),当小数部分四舍五入时会出错。
以下是纠正错误的方法(稍作修改,以十分之一秒为单位,并使用参数化格式模式)。
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