-1

私のアプリケーションは、タイムスタンプでよく機能します。多くの場合、変数のDDMMYYYY一部を切り取る必要があります。Date最初の推測は

Dim xDate as Date 
Dim xDDMMYYY as Date : xDDMMYYY = Dateserial(Year(xDate), Month(xDate), Day(xDate))

ただし、これは非常に遅いです。代わりに、より速い方法を見つけたいと思います。まずは関数を使ってみFloorます。そう ...

Public Function timeStamp2DDMMYYYY(xStamp As Date) As Date
    timeStamp2DDMMYYYY = WorksheetFunction.Floor(CDbl(xStamp), 1)                                  
End Function

ただし、これは、関数が 1900 年 1 月 3 日を返す場合、たとえば 1900 年 1 月 4 日に対して間違った結果を生成します。

Public Function timeStamp2DDMMYYYY(xStamp As Date) As Date
    ' timeStamp2DDMMYYYY = CDbl(xStamp) - modDblTimeStamps(CDbl(xStamp), 1)              ' Cut the non-whole days off
     timeStamp2DDMMYYYY = WorksheetFunction.Floor(CDbl(xStamp), 1)                             ' Cut the non-whole days off
End Function

Private Function modDblTimeStamps(xA As Double, xB As Double) As Double
    Dim xRes As Double:   xRes = xA - (CLng(xA / xB) * xB)
    If (xRes < -1 / 86400) Then xRes = xRes + xB    ' A difference between xRes and zero
                                                    ' must be at least one second to prevent
    modDblTimeStamps = xRes
End Function

ただし、これにより、たとえば 1963 年 8 月 31 日 23:59:59 の場合、不適切な動作が発生します。

私の質問は次のとおりです:この変換を達成するための高速でフェールセーフな方法はありますか?

EDIT 悪い - 最初にプロファイラーを使用する必要がありました。比較のために、提案されたすべてのソリューションを集めました。

Public Function timeStamp2DDMMYYYY_1(xStamp As Date) As Date
    timeStamp2DDMMYYYY_1 = DateSerial(Year(xStamp), Month(xStamp), Day(xStamp))
End Function

Public Function timeStamp2DDMMYYYY_2(xStamp As Date) As Date
    timeStamp2DDMMYYYY_2 = DateValue(xStamp)
End Function

Public Function timeStamp2DDMMYYYY_3(xStamp As Date) As Date
    Dim xDDMMYYY As String: xDDMMYYY = DatePart("d", xStamp) & "." & DatePart("m", xStamp) & "." & DatePart("yyyy", xStamp)
    timeStamp2DDMMYYYY_3 = CDate(xDDMMYYY)
End Function

Public Function timeStamp2DDMMYYYY_4(xStamp As Date) As Date
    timeStamp2DDMMYYYY_4 = CDate(Split(xStamp, Chr(32))(0))
End Function

Public Function timeStamp2DDMMYYYY_5(xStamp As Date) As Date
    timeStamp2DDMMYYYY_5 = CDbl(xStamp) - modDblTimeStamps(CDbl(xStamp), 1)               
End Function

Public Function timeStamp2DDMMYYYY_6(xStamp As Date) As Date
   timeStamp2DDMMYYYY_6 = Int(xStamp)
End Function

1900 年 1 月 1 日から 1905 年 12 月 31 日まで 5 分刻みで移動すると、すべての関数が正しい値を返します。プロファイリングの結果は次のとおりです。

timeStamp2DDMMYYYY_1 - 2.22199s
timeStamp2DDMMYYYY_2 - 5.62594s
timeStamp2DDMMYYYY_3 - 5.91005s
timeStamp2DDMMYYYY_4 - 6.51989s
timeStamp2DDMMYYYY_5 - 3.67998s
timeStamp2DDMMYYYY_6 - 4.29623s

結論 - 私のスロー スポットは timeStampManip モジュールの別の場所にあります。プリミティブ版が一番速いです… 皆さんありがとうございます。

4

2 に答える 2

0

あなたの目標が時間を取り除き、純粋な日付だけを残すことである場合:

Public Function StripTime(dIn As Date) As Date
    StripTime = Int(dIn)
End Function

テスト済み:

Sub MAIN()
    Dim d As Date, d2 As Date
    d = DateValue("1/18/1900") + TimeValue("9:35 PM")
    MsgBox d
    d2 = StripTime(d)
    MsgBox (d2)
End Sub
于 2013-09-05T15:45:54.333 に答える