3

I am creating a VB6 application which needs to query an existing database, and I need to do a filter by date. The database stores the dates in Windows File Time format, i.e 130159451238571322 which is 2013-06-17 12:18:43.857

Is there a way in VB6 to take the current Date/Time and convert it to a Windows File Time?

Gavin Coates
  • 1,366
  • 1
  • 20
  • 44

2 Answers2

0

After a little research, it doesn't appear to me that there are any native functions or procedures that will do this for you (in VB6, that is; VB.NET allows you to do DateTime.Today.ToFileTime) However, this article explains how Windows File Time is calculated - File Times

Taking that into consideration, you can calculate the amount of 100 nano-second intervals that have occurred between midnight of 1/1/1601 and the current date and time (UTC) to create an accurate File Time.

Dave H
  • 653
  • 12
  • 22
  • that's one potential solution, but how do I go about doing that in VB6? Also the result will be a 64bit number, can VB6 handle 64bit values? – Gavin Coates Jul 03 '13 at 14:36
0

The only 64-bit values VB6 handles natively are those of the Currency type. However those are signed 64-bit integers with implied scaling by 10,000 so a binary value 1 is treated as 0.0001 for arithmetic purposes.

However when you retrieve such "File Time" values from a database via ADO, what you get is usually a Variant of subtype Decimal. This is another creature entirely.

FILETIME is a struct, and the closest thing in VB6 is a "UDT" more properly called a record. So you get to play a little more flippity-flop when using such values with databases.

Here's an example of some of the conversions:

Option Explicit

Private Type OneCurrency
    Curr As Currency
End Type

Private Sub cmdConvert_Click()
    Dim DateTime As Date
    Dim FileTimeRecord As FILETIME
    Dim DecFileTime As Variant
    Dim OC As OneCurrency

    'Convert:
    DateTime = CDate(txtTime.Text)
    FileTimeRecord = DateToFileTime(DateTime)
    LSet OC = FileTimeRecord
    DecFileTime = CDec(OC.Curr) * CDec(10000)

    'Display:
    With FileTimeRecord
        lblFileTime.Caption = Right$(String$(7, "0") & Hex$(.dwHighDateTime), 8) _
                            & ":" _
                            & Right$(String$(7, "0") & Hex$(.dwLowDateTime), 8) _
                            & vbNewLine _
                            & CStr(DecFileTime)
    End With

    'Convert back, display:
    OC.Curr = DecFileTime / 10000@
    LSet FileTimeRecord = OC
    lblTime.Caption = CStr(FileTimeToDate(FileTimeRecord))
End Sub

Private Sub cmdNow_Click()
    txtTime.Text = CStr(Now())
End Sub

That Form code relies on a few declarations located elsewhere such as a static module:

Option Explicit

Public Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type SYSTEMTIME
    wYear As Integer
    wMonth As Integer
    wDayOfWeek As Integer
    wDay As Integer
    wHour As Integer
    wMinute As Integer
    wSecond As Integer
    wMilliseconds As Integer
End Type

Private Declare Function FileTimeToSystemTime Lib "kernel32" ( _
    ByRef lpFileTime As FILETIME, _
    ByRef lpSystemTime As SYSTEMTIME) As Long

Private Declare Function SystemTimeToFileTime Lib "kernel32" ( _
    ByRef lpSystemTime As SYSTEMTIME, _
    ByRef lpFileTime As FILETIME) As Long

Public Const ZERO_DATE As Date = 0!

Public Function DateToFileTime(ByVal DateTime As Date) As FILETIME
    Dim stLocal As SYSTEMTIME
    Dim stUniversal As SYSTEMTIME
    Dim ftResult As FILETIME

    With stLocal
        .wYear = Year(DateTime)
        .wMonth = Month(DateTime)
        .wDay = Day(DateTime)
        .wHour = Hour(DateTime)
        .wMinute = Minute(DateTime)
        .wSecond = Second(DateTime)
    End With
    SystemTimeToFileTime stLocal, ftResult
    DateToFileTime = ftResult
End Function

Public Function FileTimeToDate(ByRef FT As FILETIME) As Date
    Dim stLocal As SYSTEMTIME

    With FT
        If (.dwHighDateTime <> 0) And (.dwLowDateTime <> 0) Then
            FileTimeToSystemTime FT, stLocal
            With stLocal
                FileTimeToDate = DateSerial(.wYear, .wMonth, .wDay) _
                               + TimeSerial(.wHour, .wMinute, .wSecond)
            End With
        Else
            FileTimeToDate = ZERO_DATE
        End If
    End With
End Function

I'm not sure all of the bugs have been squashed there but it should be enough to get you started.

Bob77
  • 13,167
  • 1
  • 29
  • 37