FileGetTime & DST problem Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

FileGetTime & DST problem

28 Apr 2019, 04:58

I apologise for asking this question again, but I'm really desperate and can't get any further.

The whole problem has to do with the behavior of FileGetTime in conjunction with DST.

Let's take as an example a file that was created on February 1st at 08.00. We switched to DST on March 31st. Now we have April.

The file appears in Windows Explorer with timestamp 08.00, and this time is also specified in the properties of the file.

But FileGetTime returns the timestamp 09.00!


In a complex script I have a lot to do with copying and recreating files and have to make sure that the timestamps displayed in Windows Explorer do not change. With this behavior of FileGetTime this proves to be impossible.

What could I do? Is there an alternative to FileGetTime that returns the exact timestamp from Windows Explorer?

EDIT / PS:
CMD behaves the same way. for %a in (myfile.txt) do echo %~ta returns 09.00, not 08.00 as displayed in Explorer.
User avatar
YoucefHam
Posts: 372
Joined: 24 Aug 2015, 12:56
Location: Algeria
Contact:

Re: FileGetTime & DST problem

28 Apr 2019, 05:55

hi check this settings
https://imgur.com/a/G2BKMBa
Image
:wave: There is always more than one way to solve a problem. ;)
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

Re: FileGetTime & DST problem

28 Apr 2019, 05:59

Thank you, Youcef, but the solution should work without changing Windows settings...
User avatar
YoucefHam
Posts: 372
Joined: 24 Aug 2015, 12:56
Location: Algeria
Contact:

Re: FileGetTime & DST problem

28 Apr 2019, 06:08

believe me, windows settings can mess you up, and you will not know it.
It happened to me before
:wave: There is always more than one way to solve a problem. ;)
just me
Posts: 9458
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: FileGetTime & DST problem

28 Apr 2019, 06:10

Hi,

FileGetTime might cause some problems because it calls FileTimeToLocalFileTime():

Script2.cpp:

Code: Select all

ResultType Line::FileGetTime(LPTSTR aFilespec, TCHAR aWhichTime)
{
	OUTPUT_VAR->Assign(); // Init to be blank, in case of failure.

	if (!aFilespec || !*aFilespec)
		return SetErrorsOrThrow(true, ERROR_INVALID_PARAMETER);

	// Don't use CreateFile() & FileGetSize() size they will fail to work on a file that's in use.
	// Research indicates that this method has no disadvantages compared to the other method.
	WIN32_FIND_DATA found_file;
	HANDLE file_search = FindFirstFile(aFilespec, &found_file);
	if (file_search == INVALID_HANDLE_VALUE)
		return SetErrorsOrThrow(true);
	FindClose(file_search);

	FILETIME local_file_time;
	switch (ctoupper(aWhichTime))
	{
	case 'C': // File's creation time.
		FileTimeToLocalFileTime(&found_file.ftCreationTime, &local_file_time);
		break;
	case 'A': // File's last access time.
		FileTimeToLocalFileTime(&found_file.ftLastAccessTime, &local_file_time);
		break;
	default:  // 'M', unspecified, or some other value.  Use the file's modification time.
		FileTimeToLocalFileTime(&found_file.ftLastWriteTime, &local_file_time);
	}

	SetErrorsOrThrow(false, 0); // Indicate success.
	TCHAR local_file_time_string[128];
	return OUTPUT_VAR->Assign(FileTimeToYYYYMMDD(local_file_time_string, local_file_time));
}
Remarks

To account for daylight saving time when converting a file time to a local time, use the following sequence of functions in place of using FileTimeToLocalFileTime:

  1. FileTimeToSystemTime
  2. SystemTimeToTzSpecificLocalTime
  3. SystemTimeToFileTime

Source
just me
Posts: 9458
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: FileGetTime & DST problem  Topic is solved

28 Apr 2019, 06:50

Well,

you might want to try the following:

Code: Select all

#NoEnv
File := A_ScriptDir . "\Class_LocalTime.ahk"

FileGetTime, TimeAHK, %File%
TimeFunc := GetFileTime(File)

MsgBox, %TimeAHK% - %TimeFunc%
ExitApp


; ======================================================================================================================
; CreateFile
;     -> docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea
;     FILE_READ_ATTRIBUTES  0x0128
;     FILE_SHARE_READ       0x01 +
;     FILE_SHARE_WRITE      0x02 +- 0X07
;     FILE_SHARE_DELETE     0x04 +
;     OPEN_EXISTING         3
;     FILE_ATTRIBUTE_NORMAL 0x80
; GetFileTime
;     -> docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-setfiletime
; FileTimeToSystemTime
;     -> docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-filetimetosystemtime
; SystemTimeToTzSpecificLocalTime
;     -> docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-systemtimetotzspecificlocaltime
; ======================================================================================================================
GetFileTime(FilePath, Type := "M") {
   If !(Handle := DllCall("CreateFile", "Str", FilePath, "UInt", 0x0128, "UInt", 0x07, "Ptr", 0
                                      , "UInt", 3, "UInt", 0x80, "Ptr", 0, "UPtr"))
      Return False
   ; Aktuelle Daten einlesen
   VarSetCapacity(CTime, 8, 0)
   VarSetCapacity(ATime, 8, 0)
   VarSetCapacity(MTime, 8, 0)
   If !DllCall("GetFileTime", "Ptr", Handle, "Ptr", &CTime, "Ptr", &ATime, "Ptr", &MTime, "UInt") {
      DllCall("CloseHandle", "Ptr", Handle, "UInt")
      Return False
   }
   DllCall("CloseHandle", "Ptr", Handle, "UInt")
   ; Datum Einlesen
   VarSetCapacity(SystemTime, 16, 0)
   PFT := (Type = "C") ? &CTime : (Type = "A") ? &ATime : &MTime
   DllCall("FileTimeToSystemTime", "Ptr", PFT, "Ptr", &SystemTime)
   VarSetCapacity(LocalTime, 16, 0)
   DllCall("SystemTimeToTzSpecificLocalTime", "Ptr", 0, "Ptr", &SystemTime, "Ptr", &LocalTime, "UInt")
   Return Format("{:04}{:02}{:02}{:02}{:02}{:02}", NumGet(LocalTime,  0, "UShort")
                                                 , NumGet(LocalTime,  2, "UShort")
                                                 , NumGet(LocalTime,  6, "UShort")
                                                 , NumGet(LocalTime,  8, "UShort")
                                                 , NumGet(LocalTime, 10, "UShort")
                                                 , NumGet(LocalTime, 12, "UShort"))
}
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

Re: FileGetTime & DST problem

28 Apr 2019, 07:05

Thank you very much, just me! Unfortunately, I would be unable to implement such a complex solution myself. I will study now your script.

But maybe the following hint would allow an easier way?

The function GetDynamicTimeZoneInformation returns information about DST (https://autohotkey.com/board/topic/100422-how-do-i-get-a-files-modified-time-in-utc/):

Code: Select all

Msgbox % IsDST() ;true if DST in effect for the system, false otherwise

IsDST()
{
  VarSetCapacity(tzi, 432)
  r := DllCall("GetDynamicTimeZoneInformation", "ptr", &tzi)
  ; r = 0 means no transition dates set - DST not in use
  ; r = 1 means system is currently using standard time
  ; r = 2 means system is currently using daylight savings time
  return (r = 2)  
}
Wouldn't be possible to determine the difference between standard time and DST in the same simple way? There seems to exist a value "DaylightBias" (https://docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-gettimezoneinformation and https://docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/ns-timezoneapi-_time_zone_information). If this is the difference and the value could be get by DllCall... ?
just me
Posts: 9458
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: FileGetTime & DST problem

28 Apr 2019, 07:17

What would be simpler than

Code: Select all

FileGetTime() -> FileTimeToSystemTime() -> SystemTimeToTzSpecificLocalTime()
We had the opposite case in the German forum: FileSetTime: Sommer-/Winterzeit?.
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

Re: FileGetTime & DST problem

28 Apr 2019, 10:30

@just me: Your solution works perfectly!!! You are a schatz!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetTime & DST problem

28 Apr 2019, 12:17

FileGetTime uses local time.
The file properties dialog uses local time.
So surely they should show the same time.
How could they be different?

What Windows version is this?
Are you comparing modified with modified / created with created?

Or ... did you change the settings, so that Explorer always displays the UTC time. As demonstrated in YoucefHam's link.

[EDIT:]
- AHK's FileGetTime uses DST/non-DST (based on the current time zone, see FileTimeToLocalFileTime).
- Since Windows Vista, file properties dialogs use DST/non-DST (based on the historic time zone, see SystemTimeToTzSpecificLocalTime)
Last edited by jeeswg on 16 Jun 2019, 01:05, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

Re: FileGetTime & DST problem

28 Apr 2019, 12:29

jeeswg: My question was answered by just me and his solution solves my problems completely.

You can't reproduce the problem? Are you in a region with DST? If so, simply apply FileGetTime to a file which was last modified this year before switching to DST. You will see that FileGetTime behaves as described in my original post: the time returned by FileGetTime differs from the time displayed in Windows Explorer.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetTime & DST problem

28 Apr 2019, 14:31

- I've investigated further, on Windows 7, Explorer, and the file properties dialog. They appear to show some dates in one time zone (DST), and some dates in another time zone (non-DST). I.e. some attempt is made to display dates based on the time zone *at the time* the file was modified/created. The flaw in that approach is that you'd have to have DST ranges going back decades. (Also, if you calculate a date difference, it can be incorrect by an hour.)
- Without having the full details as I've described (although perhaps you and just me both already knew this), any solution is 'accidental', and may fail in future.
- A further complicating factor, is that while most people have 3 time zones to deal with: UTC / local (non-DST) / local (DST). For me UTC = local (non-DST). So investigations are harder to do.

Code: Select all

Note: GMT (UTC), BST (UTC+1)

AHK (FileGetTime):
modified: 19:21 28/04/2019 [local now: UTC+1]
created: 12:58 03/01/2019 [local now: UTC+1]

Windows 7 (Explorer and file properties dialog):
modified: 19:21 28/04/2019 [local now: UTC+1]
created: 11:58 03/01/2019 [local at the time?: UTC]

Winapi (FindFirstFile/FindClose/FileTimeToSystemTime):
modified: 18:21 28/04/2019 [UTC]
created: 11:58 03/01/2019 [UTC]
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
newbieforever
Posts: 493
Joined: 24 Aug 2016, 03:34

Re: FileGetTime & DST problem

28 Apr 2019, 15:11

jeeswg: Hm... Shouldn't we rather assume that the FileGetTime() -> FileTimeToSystemTime() -> SystemTimeToTzSpecificLocalTime() method (implemented in the script from just me), which is based on the explicit recommendation from Microsoft (https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-filetimetolocalfiletime), is and will remain relible???
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetTime & DST problem

28 Apr 2019, 17:26

- I tested just me's GetFileTime function, and it appears to give the same dates as Explorer, i.e. the time that you would have seen on your watch at the moment the file was modified/created.
- And just to restate what I said earlier, if one date is from a non-DST period (e.g. created), and one date is from a DST period (e.g. modified), Explorer will show you times from 2 different time zones on the same file properties dialog! (Two possible local time zones.)

- AHK's function FileGetTime will show all dates in whatever the current time zone is. It gets the UTC time and converts it to the current local time zone. (One possible local time zone.)

- FindFirstFile followed by FileTimeToSystemTime will give you dates in UTC. (One possible time zone.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetTime & DST problem

16 Jun 2019, 01:08

- I've since done some further research ...

- Some links re. how the Explorer file properties dialog displays dates.
- In short, in the past, they used FileTimeToLocalFileTime (current DST), now, from Windows Vista onwards, they use SystemTimeToTzSpecificLocalTime (historic DST).
- One consequence is that file properties dialogs may now show you dates, on the same dialog, in different time zones (some DST, some non-DST).
- (Note: the MSDN documentation for SystemTimeToTzSpecificLocalTime is pretty unclear, I only understood what it does via external sources.)

- Links (Raymond Chen on time zones and datestamps):
Windows Confidential - Evolution of the File Property Timestamp | Microsoft Docs
https://docs.microsoft.com/en-us/previous-versions/technet-magazine/ff394358(v=msdn.10)
Why Daylight Savings Time is nonintuitive | The Old New Thing
https://devblogs.microsoft.com/oldnewthing/20031024-00/?p=42053
Why do Explorer and the command prompt interpret file times differently? | The Old New Thing
https://devblogs.microsoft.com/oldnewthing/20130308-00/?p=5023

- Links (Winapi functions):
[UTC to local (based on current DST)]
FileTimeToLocalFileTime function (fileapi.h) | Microsoft Docs
https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-filetimetolocalfiletime
[UTC to local (based on historic DST)]
SystemTimeToTzSpecificLocalTime function (timezoneapi.h) | Microsoft Docs
https://docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-systemtimetotzspecificlocaltime
Time Functions - Windows applications | Microsoft Docs
https://docs.microsoft.com/en-us/windows/desktop/SysInfo/time-functions

- Links (further):
Problems and solutions with FileSetTime, FileGetTime and DST (Daylight Saving Time) enabled in Windows 7+. - AutoIt Example Scripts - AutoIt Forums
https://www.autoitscript.com/forum/topic/182494-problems-and-solutions-with-filesettime-filegettime-and-dst-daylight-saving-time-enabled-in-windows-7/
FileGetTime & DST problem - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=64093
Convert Timestamp to Local Time - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=65407
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: FanaticGuru, Google [Bot] and 335 guests