API wanted to change a files "FileDateTime"

I have my desktop with nt & notebook with windows me

both have altered the clock time for daylight saving

however the filedatetime has been altered on my notebook, and not my desktop

I have a program that compares files on both computers, normally the difference between both is what I have changed recently.

Now because of this change every file is different by one hour on my notebook.

Simplest way for me to resolve this problem is to set the files back one hour on my notebook.

How do I change a files "FileDateTime" ?
Who is Participating?

Improve company productivity with a Business Account.Sign Up

TravisHallConnect With a Mentor Commented:
You will need to declare CompareFileTime and the UDT it requires, FILETIME, before you can use them. For the appropriate declarations, look in your API Viewer (which comes with VB5 and VB6).

Then, to use it:
'...insert code to get your file times...
If CompareFileTime(ft1, ft2) = 0 Then
  'file times match
  'file times are different
End If
SetFileTime can be used to change the last modified time of a file (which is what is returned by the FileDateTime function).

However, what you describe sounds a little dodgy to me. I would be suspicious concerning whether the daylight savings adjustments really have been made correctly on both machines. Maybe there's some difference between how NT and Me handle daylight savings time that accounts for the change in file times you describe, but if so I don't know what it is and it doesn't sound right.

Rather than actually changing the last modified times of all your files, I would first try comparing the dates by converting the value you get from FileDateTime to a common time zone - I would go for GMT - without daylight savings, and see if the values come out the same. If so, use that comparison rather than your current one.

If not, SetFileTime does what you asked for.
bemsonAuthor Commented:

hanks for info, I have looked for conversion of filedatetime to gmt but no options found in vb help

could you please advise how this conversion is obtained.

Obviously if this option gives the right answer, then no need to convert times,

Also there seems to be no example in help for "SetFileTime"

any help is much appreciated
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Ryan ChongCommented:
bemsonAuthor Commented:
I don't seem to be getting very far

I have created a project as above htm document, however I cannot by modification get the time, only the date, this vb project also only changes date/time to current time.

Although as we are in Australia time is +10 hours, it should be - 10 hours to get to gmt if that is what it is doing

Also I want to set my own time not system time, so need a further mod

Unfortuneately, my web access is work related, so I will be back in 17 hours

thanks so far!
Richie_SimonettiIT OperationsCommented:
bemsonAuthor Commented:
to richie,

did not see any comments or suggestions, only your name!

did you have any contributions for me?

present status:

1. still waiting for suggestion to get gmt time format (or maybe utc?)or time format that is consistent with both nt & windows me

2. still have to modify project suggested by ryancys to set my own time & date, also his suggestion does not show time only date.

3. the project in 2 also adds 10 hours to existing clock time, my belief is that Australia is 10 hours in front of gmt, therefore date (depending on our present time being < 09:59) should be previous days date & -10 hours not + 10 hours

While looking up some of the information you have requested (in the MSDN Library - if you don't have it, get it), I came across this, in the entry for GetFileTime: "FAT records times on disk in local time. However, NTFS records times on disk in UTC."

This means, I think, that when you read the file time, you are going to have to compensate depending on what file system the file is being stored under. You should be able to obtain the file system of the drive using the Drive object from VB Scripting (which can be used in VB), though there are undoubtedly also other ways to do it (which might be better - I haven't looked into it).

If a file is stored on a FAT drive, use LocalFileTimeToFileTime to convert to UTC time, and then do your comparison.]

UTC time is the same as GMT time, by the by.

Information on all these API functions can be obtained from the Platform SDK, available as a free download from Microsoft.
bemsonAuthor Commented:
I found this in msdn

The CompareFileTime function compares two 64-bit file times.

LONG CompareFileTime(
  CONST FILETIME *lpFileTime1,  // pointer to first file time
  CONST FILETIME *lpFileTime2   // pointer to second file time
Pointer to a FILETIME structure that specifies the first 64-bit file time.
Pointer to a FILETIME structure that specifies the second 64-bit file time.
Return Values
The return value is one of the following values:

Value Meaning
-1 First file time is less than second file time.
0 First file time is equal to second file time.
+1 First file time is greater than second file time.

is this for vb or 'C'

Richie_SimonettiIT OperationsCommented:
That was due to a bug in EE:

Tip 127: Stamping Files with the Current Date and Time
July 1, 1995

While your Microsoft® Visual Basic® program is running, you may need to update the date and time stamp for a particular file. This article explains how you can set a file's date and time stamp to the current date and time setting.

Manipulating a File's Date and Time Information
The FileDateTime function in Microsoft® Visual Basic® can tell you when a specific file was first created or last modified. FileDateTime returns both the date and time information as a string variable. However, Visual Basic does not offer a function to set a file's date and time information.

The example program below shows how to update the date and time information for an already existing file. First, you need to make sure the file exists. The Dir$ function will return a NULL or empty string if it cannot find the specified file on the disk.

When you know the file exists, you can use the Visual Basic file manipulation commands—Open, Get, Put, and Close—to force the operating system to update the file's date and time stamp.

The technique is straightforward. You simply open the file, use the Get statement to retrieve the first byte from the file, and then use the Put statement to write that same byte back to the file. When you close the file, Microsoft Windows® automatically updates the file's date and time information.

Example Program
This program shows how to update a file's date and time information from within a Visual Basic application.

Create a new project in Visual Basic. Form1 is created by default.

Add a Command Button control to Form1. Command1 is created by default.

Add the following code to the Click event for Command1:
Private Sub Command1_Click()
    Dim FName As String
    Dim F As String
    Dim AnyThing As Integer
    Dim X As Integer
    FName = "c:\test.doc"
    F = Dir$(FName)
    If F = "" Then GoTo NoSuchFile
    On Error GoTo FileError
        X = FreeFile
        Open FName For Binary As X
        Get X, 1, AnyThing
        Put X, 1, AnyThing
        Close X
    MsgBox "New time/date is: " & FileDateTime("c:\test.doc"), 16, "OK"
    Exit Sub
    MsgBox "Unable to time-stamp file", 16, "Error"
    Exit Sub
    MsgBox "That file does not exist!", 16, "Error"
End Sub

Note   This example program assumes you have a file named TEST.DOC in the root directory of drive C.

Run the example program by pressing F5. Click the command button to update the file's date and time information.

Additional References
Knowledge Base Q113958. "BUG: VBApp FileCopy Updates Destination File's Date & Time Stamp."

Knowledge Base Q96098. "FileDateTime Doesn't Include Time If File Time Is Midnight."
bemsonAuthor Commented:
to ritchie:

ok so we now know you cannot alter the time of a file to suit your own needs as in my case where I wanted to set back the file time by 1 hour

only option is for system to set filedatetime by either of your examples to current timestamp which does not suit my needs, however, read on.

to Travis:

I have built the following which seems to serve my need to compare 2 file times

Module code

Public Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
End Type

Public Declare Function CompareFileTime Lib "kernel32" (lpfiletime1 As FILETIME, lpfiletime2 As FILETIME) As Long

Form Code

Private Sub Form_Load()

    Dim ft1 As FILETIME
    Dim ft2 As FILETIME
    Dim File1$
    Dim File2$
    Dim Message$
    File1$ = "c:\00\632vb\chkwxc.vbp"
    File2$ = "c:\00\0pending\632vb\chkwxc.vbp"
    Message = "#1 = " & Format(FileDateTime(File1$), "dd mmm yyyy hh:mm:ss") & vbCrLf
    Message = Message & "#2 = " & Format(FileDateTime(File2$), "dd mmm yyyy hh:mm:ss") & vbCrLf
    Message = Message & vbCrLf
    ft1.dwHighDateTime = FileDateTime(File1$)
    ft2.dwHighDateTime = FileDateTime(File2$)
    Select Case CompareFileTime(ft1, ft2)
        Case 0
            MsgBox Message & "both same"
        Case -1
            MsgBox Message & "#1 less than #2"
        Case 1
            MsgBox Message & "#1 greater than #2"
    End Select
End Sub

and indeed I get a match even though "filedatetime" shows times different by 1 hour!

which solves my compare problem in the original question

anybody who reads this may want to comment on whether there are any flaws in this code & whether I should be using dwHighDate or dwLowDate

as travis suggested the compare code, at this stage points are his.

will wait for any additional comments

thanks for help so far
>ok so we now know you cannot alter the time of a file to >suit your own needs as in my case where I wanted
>to set back the file time by 1 hour

Actually, you can - that's what SetFileTime is for. However, that's generally not a terribly good idea in general.

I have used SetFileTime to set the last modified time to a time of my choosing in the past. It was in a program which had to effectively copy some files, but which couldn't use a standard Windows copy to do it - security issues, no user existed which could access both source and destination - and it was important that the copied files have the same file times as the originals. But it's rare that this is done.

As for your time comparisons...

Your code looks fishy to me. The files you have tested on seem to be on the same drive. Have you tried doing this with one file on each machine, as in your original case?

It doesn't look valid to me to just copy the result of a call to FileDateTime to one member of a FILETIME UDT. If I understand it correctly, FileDateTime will return a VB date (stored as a variant, but still a VB date), which is equivalent to a double, where the whole number value represents the date and the fractional part represents the time. If you then coerce this to a long - which is what you have done when you just set dwHighDateTime equal to the return value of FileDateTime - the fractional part will be either dropped or rounded (can't remember which off the top of my head, but it's bad either way). You will end up doing a straight date comparison, ignoring the time part altogether. To check this, compare the file times of two different files which were both last modified at times close together, but not exactly the same.

What about using GetFileTime instead of FileDateTime to get your last modified time?

See your API Viewer for other required declarations, UDTs and constants.

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

Dim hFile as Long
GetFileTime hFile, 0, 0, ft1

CloseHandle hFile

Do something similar for the second file, and then remember to do your adjustment with LocalFileTimeToFileTime for any file that happens to be stored on a FAT drive.

Alternatively, you could come at if from a completely different direction, and use VBScript's File object to get your last modified times - it presents it to you as a property. And while you are at it, you can check the drive format with the Drive object, since you have had to go to the trouble of using a FileSystemObject in the first place.

Dim fso As FileSystemObject
Dim fil1 As File
Dim fil2 As File
Dim drv1 As Drive
Dim drv2 As Drive
Dim dMod1 As Date
Dim dMod2 As Date

Set fso = New FileSystemObject
Set fil1 = fso.GetFile(File1$)
Set fil2 = fso.GetFile(File2$)

Set drv1 = fso.GetDrive(fil1.Drive)
Set drv2 = fso.GetDrive(fil2.Drive)

If drv1.FileSystem = "FAT" Or drv1.FileSystem = "FAT32" Then
  dMod2 = DateToUTCDate(fil1.DateLastModified)
  dMod1 = fil1.DateLastModified
End If

If drv2.FileSystem = "FAT" Or drv2.FileSystem = "FAT32" Then
  dMod2 = DateToUTCDate(fil2.DateLastModified)
  dMod2 = fil2.DateLastModified
End If

If dMod1 = dMod2 Then
  'file times the same
  'File times different
End If

And you will need this functions:
Private Function DateToUTCDate(d As Date)

st.wDay = Day(d)
st.wHour = Hour(d)
st.wMilliseconds = 0
st.wMinute = Minute(d)
st.wMonth = Month(d)
st.wSecond = Second(d)
st.wYear = Year(d)
SystemTimeToFileTime st, ft
LocalFileTimeToFileTime ft, ft
FileTimeToSystemTime ft, st
DateToUTCDate = DateSerial(st.wYear, st.wMonth, st.wDay) + TimeSerial(st.wHour, st.wMinute, st.wSecond)
End Sub

And check API Viewer for other required declarations and such.

Bear in mind, that's completely untested code straight off the top of my head. I make no promises that it will work, though I'm confident of the underlying principle.

Come to think of it, using the scripting objects should be a much easier way to come at it in VB. If this program is just supposed to check names and file times and do a straight copy or such, I'd probably switch to C++ for this one - it's less fuss to use the API in C++. But in VB, you can use those scripting objects with little fuss.
bemsonAuthor Commented:
Thanks also to ryancys & ritchie for suggestions

To explore these options is going to take some time, so I will experiment with them next week & re-visit this topic if I get frustrated with results

thanks again to all contributors
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.