Visual Basic File API Routines
SetFileTime: Obtain and Change a File's Created, Accessed and Modified Dates
     
Posted:   Saturday March 4, 1998
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB5, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

SetFileTime: Modify the Date/Time of Folders and Files
     
 Prerequisites
None.

The Win32 API supports five time formats (time discussed herein also refers to date). Time-related functions return time in one of these formats:

SYSTEMTIME (System) - Year, month, day, hour, second, and millisecond, taken from the internal hardware clock.

FILETIME (File) - 100-nanosecond intervals since January 1, 1601.

SYSTEMTIME or FILETIME (Local) - A system time or file time converted to the system's local time zone.

MS-DOS (WORD) - A packed 16-bit word for the date, another for the time.

Windows (DWORD) - The number of milliseconds since the system booted; a quantity that cycles every 49.7 days.

The Win32 API includes functions to convert between time formats for ease of comparison and display. The Win32 API also provides functions to convert certain time formats based on the time zone.

This project will use the local FILETIME and SYSTEMTIME structures to obtain a file's Created, Last Accessed and Last Modified dates, obtain the local system time with consideration for the time zone offset from GMT, and convert the system time into a new FILETIME structure which can then be used to reset any or all of the file's date attributes.

 

 BAS Module Code
None.

 Form Code
The form is a simple set of textboxes (from top to bottom Text1 (the filename), Text2 (the original date), Text3 (system date data) and Text4 (the new file data info)), and three command buttons (Command1, Command2 and Command3).  Labels are optional.

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const OFS_MAXPATHNAME = 128
Private Const OF_READWRITE = &H2

Private Type OFSTRUCT
   cBytes      As Byte
   fFixedDisk  As Byte
   nErrCode    As Integer
   Reserved1   As Integer
   Reserved2   As Integer
   szPathName(0 to OFS_MAXPATHNAME -1) As Byte  '0-based
End Type

Private 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 Type TIME_ZONE_INFORMATION
   Bias         As Long
   StandardName(0 to 31) As Integer  '32, 0-based
   StandardDate As SYSTEMTIME
   StandardBias As Long
   DaylightName(0 to 31) As Integer  '32, 0-based
   DaylightDate As SYSTEMTIME
   DaylightBias As Long
End Type

Private Declare Sub GetLocalTime Lib "kernel32" _
   (lpSystemTime As SYSTEMTIME)

Private Declare Function GetFileTime Lib "kernel32" _
   (ByVal hFile As Long, lpCreationTime As FILETIME, _
    lpLastAccessTime As FILETIME, _
    lpLastWriteTime As FILETIME) As Long
    
Private Declare Function SetFileTime Lib "kernel32" _
   (ByVal hFile As Long, _
    lpCreationTime As FILETIME, _
    lpLastAccessTime As FILETIME, _
    lpLastWriteTime As FILETIME) As Long

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

Private Declare Function OpenFile Lib "kernel32" _
   (ByVal lpFileName As String, _
    lpReOpenBuff As OFSTRUCT, _
    ByVal wStyle As Long) As Long
    
Private Declare Function CloseHandle Lib "kernel32" _
   (ByVal hFile As Long) As Long

Private Type SHELLEXECUTEINFO
    cbSize        As Long
    fMask         As Long
    hwnd          As Long
    lpVerb        As String
    lpFile        As String
    lpParameters  As String
    lpDirectory   As String
    nShow         As Long
    hInstApp      As Long
    lpIDList      As Long
    lpClass       As String
    hkeyClass     As Long
    dwHotKey      As Long
    hIcon         As Long
    hProcess      As Long
End Type

Private Const SEE_MASK_INVOKEIDLIST = &HC
Private Const SEE_MASK_NOCLOSEPROCESS = &H40
Private Const SEE_MASK_FLAG_NO_UI = &H400

Private Declare Function ShellExecuteEx Lib "shell32" _
  Alias "ShellExecuteEx" _
  (SEI As SHELLEXECUTEINFO) As Long



Private Sub Command1_Click()

   Unload Me
   
End Sub


Private Sub Command2_Click()

  'variables required
   Dim hFile As Long
   Dim fName As String
   Dim tmp As String
   
  'structures required
   Dim OFS As OFSTRUCT
   Dim SYS_TIME As SYSTEMTIME
   Dim FT_CREATE As FILETIME
   Dim FT_ACCESS As FILETIME
   Dim FT_WRITE As FILETIME
   Dim NEW_TIME As FILETIME
    
  'assign the textbox entry to the filename
   fName = (Text1)
   
  'open the file
   hFile = OpenFile(fName, OFS, OF_READWRITE)
   
  'get the FILETIME info for the created,
  'accessed and last write info
   Call GetFileTime(hFile, FT_CREATE, FT_ACCESS, FT_WRITE)
      
  '----- debug only ---------------------------
  'show the system time info
   tmp = "Date Created:" & vbTab & GetFileDateString(FT_CREATE) & vbCrLf
   tmp = tmp & "Last Access:" & vbTab & GetFileDateString(FT_ACCESS) & vbCrLf
   tmp = tmp & "Last Modified:" & vbTab & GetFileDateString(FT_WRITE)
   Text2.Text = tmp
  '--------------------------------------------
  
  'obtain the local system time
  '(adjusts for the GMT deviation
  'of the local time zone)
   GetLocalTime SYS_TIME
   
  '----- debug only ---------------------------
  'show the system time info
   tmp = ""
   tmp = "Day:" & vbTab & SYS_TIME.wDay & vbCrLf
   tmp = tmp & "Month:" & vbTab & SYS_TIME.wMonth & vbCrLf
   tmp = tmp & "Year:" & vbTab & SYS_TIME.wYear & vbCrLf
   tmp = tmp & "String:" & vbTab & GetSystemDateString(SYS_TIME)
   Text3.Text = tmp
  '--------------------------------------------
     
  'convert the system time to a valid file time
   Call SystemTimeToFileTime(SYS_TIME, NEW_TIME)
   
     
  'set the created, accessed and modified dates all
  'to the new dates.  A null (0&) could be passed as
  'any of the NEW_TIME parameters to leave that date unchanged.
   Call SetFileTime(hFile, NEW_TIME, NEW_TIME, NEW_TIME)
   
  're-read the updated FILETIME info for the created,
  'accessed and last write info
   Call GetFileTime(hFile, FT_CREATE, FT_ACCESS, FT_WRITE)
      
  '----- debug only ---------------------------
  'show the system time info
   tmp = "New Date Created:" & vbTab & GetFileDateString(FT_CREATE) & vbCrLf
   tmp = tmp & "New Last Access:" & vbTab & GetFileDateString(FT_ACCESS) & vbCrLf
   tmp = tmp & "New Last Modified:" & vbTab & GetFileDateString(FT_WRITE)
   Text4.Text = tmp
  '--------------------------------------------
   
  'clean up by closing the file
   Call CloseHandle(hFile)

End Sub


Private Sub Command3_Click()

    Dim SEI As SHELLEXECUTEINFO
    
   'Fill in the SHELLEXECUTEINFO structure
   'and call the ShellExecuteEx API
    With SEI
        .cbSize = Len(SEI)
        .fMask = SEE_MASK_NOCLOSEPROCESS Or _
                 SEE_MASK_INVOKEIDLIST Or _
                 SEE_MASK_FLAG_NO_UI
        .hwnd = Me.hwnd
        .lpVerb = "properties"
        .lpFile = (Text1)
        .lpParameters = vbNullChar
        .lpDirectory = vbNullChar
        .nShow = 0
        .hInstApp = 0
        .lpIDList = 0
    End With
    
   'call the API
    Call ShellExecuteEx(SEI)

End Sub


Private Function GetFileDateString(CT As FILETIME) As String

  Dim ST As SYSTEMTIME
  Dim ds As Single
  
 'convert the passed FILETIME to a
 'valid SYSTEMTIME format for display 
  If FileTimeToSystemTime(CT, ST) Then
     ds = DateSerial(ST.wYear, ST.wMonth, ST.wDay)
     GetFileDateString = Format$(ds, "DDDD MMMM D, YYYY")
  Else
     GetFileDateString = ""
  End If

End Function


Private Function GetSystemDateString(ST As SYSTEMTIME) As String

  Dim ds As Single
  
  ds = DateSerial(ST.wYear, ST.wMonth, ST.wDay)
  
  If ds Then
     GetSystemDateString = Format$(ds, "DDDD MMMM D, YYYY")
  Else
     GetSystemDateString = "error!"
  End If

End Function
 Comments
Run your project, and enter a valid path and filename. Press the Change button to update the dates to the current system time.  The Prove It button will launch the property page for the entered file, so you can see the changes actually reflected.

There is another API that which encapsulates the GetSystemTime and SystemTimeToFileTime APIs into one API - GetSystemTimeAsFileTime. I chose not to use this as it retrieved the system time instead of the local time, resulting in the date being off by five hours because of the five hour difference in time between GMT and Toronto.

Finally, although the code above looks like a lot just to change the flippin' time, in the actual routine (minus the comments and debug code with an error check on the file handle) is only a half dozen lines:

   Dim hFile As Long
   Dim fName As String
   Dim tmp As String
   Dim OFS As OFSTRUCT
   Dim SYS_TIME As SYSTEMTIME
   Dim FT_CREATE As FILETIME
   Dim FT_ACCESS As FILETIME
   Dim FT_WRITE As FILETIME
   Dim NEW_TIME As FILETIME
   
   fName = (Text1.Text)
  
   hFile = OpenFile(fName, OFS, OF_READWRITE)
  
   If hFile Then
  
      GetLocalTime SYS_TIME
      Call GetFileTime(hFile, FT_CREATE, FT_ACCESS, FT_WRITE)
      Call SystemTimeToFileTime(SYS_TIME, NEW_TIME)
      Call SetFileTime(hFile, NEW_TIME, NEW_TIME, NEW_TIME)
  
   End If
  
   Call CloseHandle(hFile)


 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter