Jump to content

FileGetTime() uses an improper TZ+DST shift at today's date


Go to solution Solved by LaurentC,

Recommended Posts

  • Developers

Is something like this what you are looking for? 

#include <Date.au3>
#include <Array.au3>

ConsoleWrite(_FileGetTimeDST("c:\test\2016-12-25 18.09.16.jpg", 2) & @CRLF)
_ArrayDisplay(_FileGetTimeDST("c:\test\2016-12-25 18.09.16.jpg", 2, 1))


Func _FileGetTimeDST($iFilename, $iOption = 0, $iFormat = 0)
    If Not FileExists($iFilename) Then Return SetError(1, 0, "File not found")
    If $iOption < 0 Or $iOption > 2 Then Return SetError(2, 0, "Wrong open parameter value")
    If $iFormat < 0 Or $iFormat > 1 Then Return SetError(3, 0, "Wrong Format parameter value")
    ; Get your timezone UTC offset in minutes
    $aInfo = _Date_Time_GetTimeZoneInformation()
    $ZONEBias = $aInfo[1] * -1
    ; Read file date-time in UTC
    $hFile = _WinAPI_CreateFile($iFilename, 2)
    If $hFile = 0 Then SetError(3, 0, "Unable to open file")
    Local $filetime = _Date_Time_GetFileTime($hFile)
    _WinAPI_CloseHandle($hFile)
    $fileUTCdate = _Date_Time_FileTimeToStr($filetime[$iOption], 1)
    $fileLOCdate = _DateAdd("n", $ZONEBias, $fileUTCdate)
    ; Return array for format 1
    If $iFormat = 1 Then Return StringSplit($fileLOCdate, "/: ", 2)
    ; return Date string for format 0
    Return $fileLOCdate
EndFunc   ;==>_FileGetTimeDST

Parameters are the same a FileGetTime().

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Hi Jos 

You're 10x times faster than me 

I can't compete    ; -)    

Well 

I have tried your proposal, but it does not fix my DST issue in all cases, because on one of my files, it goes to 18h, and with the other to 17h... 

As promised, I have developed my own code that I insert inside your above example 

I have followed Microsoft documentation recommendations below and it works for me    😄   

My test code at this point implements only options $FT_MODIFIED (0) and $FT_STRING (1) I use for FileGetTime()... 

Regards 

#include <Date.au3>
#include <Array.au3>

_ArrayDisplay(_FileGetTimeDST("TEST 20190115_180000.txt", 2, 1))

_ArrayDisplay(_FileGetTimeDST("TEST 20190715_180000.txt", 2, 1))

Func _FileGetTimeDST($iFilename, $iOption = 0, $iFormat = 0)

    If Not FileExists($iFilename) Then Return SetError(1, 0, "File not found")
    If $iOption < 0 Or $iOption > 2 Then Return SetError(2, 0, "Wrong open parameter value")
    If $iFormat < 0 Or $iFormat > 1 Then Return SetError(3, 0, "Wrong Format parameter value")

    Local $hFile = _WinAPI_CreateFile($iFilename, 2)
    If $hFile = 0 Then
        _WinAPI_ShowError("ERROR: _WinAPI_CreateFile open " & $iFilename)
        MsgBox(0, "Error", "ERROR: _WinAPI_CreateFile open " & $iFilename)
        Exit
    EndIf
    Local $aTime = _Date_Time_GetFileTime($hFile)
    _WinAPI_CloseHandle($hFile)
    $aTime = $aTime[2]
    Local $tSystem = _Date_Time_FileTimeToSystemTime($aTime)
    Local $tLocal = _Date_Time_SystemTimeToTzSpecificLocalTime($tSystem)
    Local $LocalStr = _Date_Time_SystemTimeToDateTimeStr($tLocal,1) ; Returns yyyy/mm/dd hh:mm:ss
    ; Use the standard FileGetTime format : YYYYMMDDHHMMSS
    $LocalStr = StringRegExpReplace($LocalStr,"^(....)/(..)/(..) (..):(..):(..)$","\1\2\3\4\5\6")
    MsgBox(0, "", "_Date_Time_SystemTimeToTzSpecificLocalTime : " & $LocalStr)
    Return $LocalStr

EndFunc   ;==>_FileGetTimeDST

 

Edited by LaurentC
Link to comment
Share on other sites

  • Solution

Hi 

I have tried to code a kind of "UDF"...   😉   

What do you think of this _FileGetTimeDST() alternative ? 

Regards 

;
; https://www.autoitscript.com/forum/topic/205935-filegettime-uses-an-improper-tzdst-shift-at-todays-date/
; https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times
;

; Debug à commenter pour le Build F7 d'un *.EXE
;#include "..\..\Dbug\_Dbug.au3"

; À commenter si usage de _Dbug.au3 et à décommenter pour le Build F7 d'un *.EXE...
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <Constants.au3>
#include <file.au3>
#include <Date.au3>
#include <Array.au3>

_ArrayDisplay(_FileGetTimeDST("TEST 20190115_180000.txt"))
MsgBox(0, "TEST 20190115_180000.txt", "Returned string = " & _FileGetTimeDST("TEST 20190115_180000.txt", 0, 1))

_ArrayDisplay(_FileGetTimeDST("TEST 20190715_180000.txt"))
MsgBox(0, "TEST 20190715_180000.txt", "Returned string = " & _FileGetTimeDST("TEST 20190715_180000.txt", 0, 1))

#cs

    Title:          _FileGetTimeDST() = FileGetTime() alternative for DST
    Filename:       N/A = Inline code in autoitscript.com forum
    Description:    Get file date & time taking into account the DST shift with your Windows local TZ
                    /!\ Windows local TZ only : no use of the real geolocation information in a file as EXIF inside a photo
                    The date & time returned are thus compliant with W7/W10 Windows File Explorer new display rule for files properties...
    Author:         LaurentC
    Version:        1.0
    Date:           06/06/2021
    Requirements:   AutoIt 3.3.14.5, Developed/Tested on W10 20H2 French
    Uses:           Constants.au3, file.au3, Date.au3, Array.au3
    Usage :         _FileGetTimeDST ( filename [, option = 0 [, format = 0]] )
                    Parameters
                    filename: The path to the file or directory to check
                    option: [optional] Flag to indicate which timestamp
                        $FT_MODIFIED (0) = Last modified (default)
                        $FT_CREATED (1) = Created
                        $FT_ACCESSED (2) = Last accessed
                    Constants are defined in FileConstants.au3
                    format: [optional] to specify type of return
                        $FT_ARRAY (0) = return an array (default)
                        $FT_STRING (1) = return a string YYYYMMDDHHMMSS
                    Constants are defined in FileConstants.au3

#ce

Func _FileGetTimeDST($filename, $option = 0, $format = 0)

    If Not FileExists($filename) Then Return SetError(1, 0, "Unable to find  file")
    If $option < 0 Or $option > 2 Then Return SetError(2, 0, "Bad option value")
    If $format < 0 Or $format > 1 Then Return SetError(3, 0, "Bad format value")

    Local $hFile = _WinAPI_CreateFile($filename, 2)
    If $hFile = 0 Then Return SetError(3, 0, "Unable to open file")
    Local $tFileTime = _Date_Time_GetFileTime($hFile)
    _WinAPI_CloseHandle($hFile)
    if $option = 0 Then $tFileTime = $tFileTime[2] ; Date Modified
    if $option = 1 Then $tFileTime = $tFileTime[0] ; Date Created
    if $option = 2 Then $tFileTime = $tFileTime[1] ; Date Accessed
    Local $localStr
    $localStr = _Date_Time_FileTimeToStr($tFileTime,1) ; Returns yyyy/mm/dd hh:mm:ss
    ;MsgBox(0, "", "_Date_Time_GetFileTime                     : " & $localStr)

    Local $tSystemTime = _Date_Time_FileTimeToSystemTime($tFileTime)
    $localStr = _Date_Time_SystemTimeToDateTimeStr($tSystemTime,1) ; Returns yyyy/mm/dd hh:mm:ss
    ;MsgBox(0, "", "_Date_Time_FileTimeToSystemTime            : " & $localStr)

    Local $tLocalTime = _Date_Time_SystemTimeToTzSpecificLocalTime($tSystemTime)
    $localStr = _Date_Time_SystemTimeToDateTimeStr($tLocalTime,1) ; Returns yyyy/mm/dd hh:mm:ss
    ;MsgBox(0, "", "_Date_Time_SystemTimeToTzSpecificLocalTime : " & $localStr)
    ; Use the standard FileSetTime format : YYYYMMDDhhmmss
    $localStr = StringRegExpReplace($localStr,"^(....)/(..)/(..) (..):(..):(..)$","\1\2\3\4\5\6")
    ;MsgBox(0, "", "_Date_Time_SystemTimeToTzSpecificLocalTime : " & $localStr)

    Local $tLocalFileTime = _Date_Time_SystemTimeToFileTime($tLocalTime)
    Local $localArray = _Date_Time_FileTimeToArray($tLocalFileTime)
    Local $localSwitchYear = $localArray[2]
    $localArray[2] = $localArray[1]
    $localArray[1] = $localArray[0]
    $localArray[0] = $localSwitchYear
    _ArrayDelete($localArray, 7)
    _ArrayDelete($localArray, 6)
    ;_ArrayDisplay($localArray)

    If $format = 0 Then
        Return($localArray)
    Else
        Return($localStr)
    EndIf

EndFunc ; _FileGetTimeDST()

 

Edited by LaurentC
Link to comment
Share on other sites

1 hour ago, JockoDundee said:

Actually God created Time.

It was included in his v1.00 package.

Code can be found here :)

Not for newbie   😁   

Sorry, there is a problem

This forum is only available to those in the Active Members group. Please see this post for details.

Error code: 2F173/K

Link to comment
Share on other sites

12 hours ago, JockoDundee said:

Here’s the code - don’t tell anyone where you got it...

;Men life 1.0 written by God

$Hours = 8
$Dead = False

Do
    Work($Hours)
    Play($Hours)
    Sleep($Hours)

Until $Dead = True

 

Excellent !

 

Yes, there are many happy philosophers here !   😂  

 

And $Dead = False again with Heaven !

 

 

Hey, I'm discovering I just about to go into Forum Heaven !

 

Members --> Active Members 20 posts :

Active Members - Members with more than 20 posts have additional rights

  • No adverts
  • Slightly more generous attachment and PM limits
  • Access to the Chat forum
  • Ability to upload files to the Downloads section

Yes 😀 !

 

See your God's men software 1.0 post now   😉  

Edited by Melba23
Merged multiple successive posts
Link to comment
Share on other sites

  • Moderators

LaurentC,

We frown on post count padding - although I understand why you did it. Please do not do it again!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

52 minutes ago, Melba23 said:

...although I understand why you did it...

Are there other tangible rewards to be gained after other even higher posting milestones are reached?

What am I missing out on that I don’t know about? :)

Code hard, but don’t hard code...

Link to comment
Share on other sites

1 hour ago, Melba23 said:

LaurentC,

We frown on post count padding - although I understand why you did it. Please do not do it again!

M23

Hi Melba23

I frown on post count padding too, but I'm sure you will have seen it was just 3 out of the needed count, and that I do not post empty things here 😊 in the topic or in all topics

Regards

Link to comment
Share on other sites

Off-Topic :

5 hours ago, JockoDundee said:

Are there other tangible rewards to be gained after other even higher posting milestones are reached?

What am I missing out on that I don’t know about? :)

Here a list of user groups and rights :

https://www.autoitscript.com/forum/topic/37739-forum-information-and-faqs/

Excerpt (modified)  :

Quote

Ranks based on increasing post count are as follows:

Seeker(up to 49 posts), Wayfarer(50+), Adventurer(100+), Prodigy(150+), Polymath(200+), Universalist(250+)

These titles are auto-generated and have no relation to actual skill level. Once you reach 300 posts you can change the title to whatever you like.

Possibly of interest for you : If you have 300+ posts, you can change your title :).

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

If a DST UDF is being contemplated, will the historic rules be embedded to make previous years (going back to the first time for every country) be accurate? I can imagine a large database or lookup table will be needed. Finding the information will be the biggest challenge I think.

Link to comment
Share on other sites

You can download everything here for free: https://www.iana.org/time-zones

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I thank you jchd

I remember you gave us also that :

On 5/25/2021 at 1:56 PM, jchd said:

Look at how complex things are in practice: the tz database is modified several times a year and it's really a huge thing!

https://en.wikipedia.org/wiki/Tz_database


Regards

PS : Remind that I have never said in this post to have the intent to correct all UTC-TZ-DST cases : very hard stuff. Just to let FileGetTime() display date-time as the new W7/W10 properties window...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...