Solved

API wanted to change a files "FileDateTime"

Posted on 2002-04-02
13
470 Views
Last Modified: 2012-05-04
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" ?
0
Comment
Question by:bemson
  • 6
  • 4
  • 2
  • +1
13 Comments
 
LVL 2

Expert Comment

by:TravisHall
ID: 6914361
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.
0
 

Author Comment

by:bemson
ID: 6914565
Travis,

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
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 6914578
0
 

Author Comment

by:bemson
ID: 6915028
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!
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6915554
0
 

Author Comment

by:bemson
ID: 6916328
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
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 2

Expert Comment

by:TravisHall
ID: 6916661
bemson,

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.
0
 

Author Comment

by:bemson
ID: 6916823
I found this in msdn

CompareFileTime
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
);
 
Parameters
lpFileTime1
Pointer to a FILETIME structure that specifies the first 64-bit file time.
lpFileTime2
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'

WHAT IS A CODE EXAMPLE FOR VB?
0
 
LVL 2

Accepted Solution

by:
TravisHall earned 100 total points
ID: 6916840
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:
Dim ft1 As FILETIME
Dim ft2 As FILETIME
'...insert code to get your file times...
If CompareFileTime(ft1, ft2) = 0 Then
  'file times match
Else
  'file times are different
End If
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6917080
That was due to a bug in EE:
From MSDN

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

Abstract
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
FileError:
    MsgBox "Unable to time-stamp file", 16, "Error"
    Exit Sub
NoSuchFile:
    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."
0
 

Author Comment

by:bemson
ID: 6917120
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
   
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
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6917235
>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
hFile = CreateFile(File1$, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
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)
Else
  dMod1 = fil1.DateLastModified
End If

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

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


And you will need this functions:
Private Function DateToUTCDate(d As Date)
Dim st As SYSTEMTIME
Dim ft As FILETIME

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.
0
 

Author Comment

by:bemson
ID: 6919376
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
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now