Announcement

Collapse
No announcement yet.

Learning the alternate form of DIR$

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Learning the alternate form of DIR$

    Over the weekend I tried out the new, alternate form of DIR$()
    Code:
    file$ = DIR$(mask$ [, [ONLY] attribute&, TO DirDataVar])
    I wanted to see if I could display the various Dates via the DIRDATA structure. Someone else had written a GetFileDateTime() function that seemed pretty applicable, but the FUNCTION takes a FileTime structure as its parameter, and the DIRDATA structure's dates are Quads.

    Here's the FUNCTION, with thanks to the original author. (I made minor changes to the format of the return string.)
    Code:
    '------------------------------------------------------------
    Function GetFileDateTime(dt As FILETIME) As String
    
        Local lpsystime As SYSTEMTIME
        Local szDate    As Asciiz * 64 ' date buffer, %LDT_SIZE = 64 bytes
        Local szTime    As Asciiz * 64 ' time buffer, %LDT_SIZE = 64 bytes
    
        'convert given date to correct format
        Call FileTimeToLocalFileTime(dt, dt)
        Call FileTimeToSystemTime(dt, lpsystime)
    
        Call GetDateFormat (%LOCALE_USER_DEFAULT, %NULL, _
          ByVal VarPtr(lpsystime), "yyyy'-'MM'-'dd", szDate, SizeOf(szDate))
    '      ByVal VarPtr(lpsystime), "yyyy'/'MM'/'dd", szDate, SizeOf(szDate))
    
        Call GetTimeFormat (%LOCALE_USER_DEFAULT, %TIME_FORCE24HOURFORMAT, _
          ByVal VarPtr(lpsystime), "HH':'mm':'ss" , szTime, SizeOf(szTime))
    
        'Function = szDate & "  " & szTime
        Function = szDate & $Spc & szTime
    
    End Function

    In my simplistic coding style, here's what I did in order to make it work:
    Code:
    #Compile Exe
    #Dim All
    #Include "win32api.inc"
    
    'DIR$ equates
    %NORMAL = 0
    %HIDDEN = 2
    %SYSTEM = 4
    %VLABEL = 8
    %SUBDIR = 16
    
    Union ftUnion      'for use with PB's new DIR$(..., TO DirData_var)
        q  As Quad
        ft As FILETIME
    End Union
    
    Function PBMain () As Long
    
       Local FileData As DIRDATA, sResult As String
       sResult = Dir$("E:\INFO - PB\_ FORUMS - PB support website\Forum 7 - Source Code", %SUBDIR, To FileData)
       MsgBox FileData.FileName
       Local ftq As ftUnion               'DIRDATA's dates are QUADS; convert to FileTime  -->>  ftq.q  vs ftq.ft
       ftq.q = FileData.CreationTime      'load the QUAD into the union's quad member
       MsgBox GetFileDateTime(ftq.ft)     'pass it as a FileTime param
    End Function
    It works, but I'd appreciate feedback - is there a better or simpler way?

    Thanks,
    -JohnM

    #2
    Use HI/LO functions...Also - VARPTR is not required on GetDateFormat and GetTimeFormat...

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "win32api.inc"
    
    FUNCTION GetFileDateTime(dt AS FILETIME) AS STRING
    
        LOCAL lpsystime AS SYSTEMTIME
        LOCAL szDate    AS ASCIIZ * 64 ' date buffer, %LDT_SIZE = 64 bytes
        LOCAL szTime    AS ASCIIZ * 64 ' time buffer, %LDT_SIZE = 64 bytes
    
        'convert given date to correct format
        CALL FileTimeToLocalFileTime(dt, dt)
        CALL FileTimeToSystemTime(dt, lpsystime)
    
        CALL GetDateFormat(%LOCALE_USER_DEFAULT, %NULL, lpsystime, "yyyy'-'MM'-'dd", szDate, SIZEOF(szDate))
    
        CALL GetTimeFormat (%LOCALE_USER_DEFAULT, %TIME_FORCE24HOURFORMAT, lpsystime, "HH':'mm':'ss" , szTime, SIZEOF(szTime))
    
        FUNCTION = szDate & $SPC & szTime
    
    END FUNCTION
    
    'DIR$ equates
    %NORMAL = 0
    %HIDDEN = 2
    %SYSTEM = 4
    %VLABEL = 8
    %SUBDIR = 16
    
    FUNCTION PBMAIN () AS LONG
    
       LOCAL FileData AS DIRDATA, sResult AS STRING
       
       LOCAL ft       AS FILETIME
       
       sResult = DIR$("C:\PBWIN80", %SUBDIR, TO FileData)
       
       MSGBOX FileData.FileName
       
       ft.dwLowDateTime = LO(DWORD, FileData.CreationTime)
       ft.dwHighDateTime = HI(DWORD, FileData.CreationTime)
       
       MSGBOX GetFileDateTime(ft)
       
    END FUNCTION
    Adam Drake
    PowerBASIC

    Comment


      #3
      >VARPTR is not required on GetDateFormat and GetTimeFormat...

      That would depend on the exact form of the DECLARE statement for the call and the syntax used at the point of the call. That's true not just of GetDateFormat/GetTimeFormat, but for any external function.

      You need an override (BYVAL, BYREF or BYCOPY) whenever the point-of-call parameter variable does not match the DECLARE for that parameter position.

      "Sometimes" the compiler helps out (with strings especially ) by "intuiting" what you need to do but IMO 'tis a bad habit to acquire to think the compiler will always "cover your body parts."

      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


        #4
        The declares distributed with PB are as follows:

        8.04:

        Code:
        DECLARE FUNCTION GetDateFormat LIB "KERNEL32.DLL" ALIAS "GetDateFormatA" (BYVAL Locale AS LONG, BYVAL dwFlags AS DWORD, lpDate AS SYSTEMTIME, lpFormat AS ASCIIZ, lpDateStr AS ASCIIZ, BYVAL cchDate AS LONG) AS LONG
        DECLARE FUNCTION GetTimeFormat LIB "KERNEL32.DLL" ALIAS "GetTimeFormatA" (BYVAL Locale AS LONG, BYVAL dwFlags AS DWORD, lpTime AS SYSTEMTIME, lpFormat AS ASCIIZ, lpTimeStr AS ASCIIZ, BYVAL cchTime AS LONG) AS LONG
        9.00:

        Code:
        DECLARE FUNCTION GetDateFormat LIB "KERNEL32.DLL" ALIAS "GetDateFormatA" (BYVAL Locale AS LONG, BYVAL dwFlags AS DWORD, lpDate AS SYSTEMTIME, lpFormat AS ASCIIZ, lpDateStr AS ASCIIZ, BYVAL cchDate AS LONG) AS LONG
        DECLARE FUNCTION GetTimeFormat LIB "KERNEL32.DLL" ALIAS "GetTimeFormatA" (BYVAL Locale AS LONG, BYVAL dwFlags AS DWORD, lpTime AS SYSTEMTIME, lpFormat AS ASCIIZ, lpTimeStr AS ASCIIZ, BYVAL cchTime AS LONG) AS LONG
        VARPTR is not required.
        Adam Drake
        PowerBASIC

        Comment


          #5
          Thanks for taking a look and making suggestions - you just never know when you're going to learn something new on top of learning something new...

          Thanks,
          -JohnM

          Comment


            #6
            OK, in the above code, I've made the following mods:

            Code:
               Local FileData As DIRDATA, sResult As String
               sResult = Dir$(DestinationFile, Only %NORMAL, To FileData)  
            
                  m1$ = "FileDates(i).Filespec:  " & FileDates(i).Filespec & $CrLf & _
                        "FileDates(i).EndDate:   " & FileDates(i).EndDate  & $CrLf & _
                        "FileData.FileName:      " & FileData.FileName     & $CrLf & $CrLf
            
                  Local ft As FileTime
                  ft.dwLowDateTime  = Lo(Dword, FileData.CreationTime)     ' thanks Adam!
                  ft.dwHighDateTime = Hi(Dword, FileData.CreationTime)
                  m2$ =       "Creation stamp:    " & GetFileDateTime(ft) & $CrLf      '
            
                  ft.dwLowDateTime  = Lo(Dword, FileData.LastWriteTime)
                  ft.dwHighDateTime = Hi(Dword, FileData.LastWriteTime)
                  m2$ = m2$ & "LastWrite stamp:   " & GetFileDateTime(ft) & $CrLf      '
            
                  ft.dwLowDateTime  = Lo(Dword, FileData.LastAccessTime)
                  ft.dwHighDateTime = Hi(Dword, FileData.LastAccessTime)
                  m2$ = m2$ & "LastAccess stamp:  " & GetFileDateTime(ft)              'sometime during this process
                  
                  GenericMessageBox m1$ & $CrLf & m2$, %mb_iconexclamation, "Results"       'thanks, MCM!
            Question:
            The only other tool I have that can show all 3 file date/time stamps is zTreeWin. For FileA, it shows:
            Code:
            Creation:       2008-11-25 19:15:04    'when I first copied it...
            LastWrite:      2008-11-25 19:15:05    '...and the moment after
            LastAccess:     2008-12-08 22:33:14    'OK, that's during this run.
            But my display for that file (using the code in this message) shows:
            Code:
            Creation stamp:       2008-12-08 22:36:33    'during this run? <<===  NO WAY!!! 
            LastWrite stamp:      2008-11-25 19:15:05    ' matches the zTree report
            LastAccess stamp:     2008-12-08 22:36:33    'OK, that's during this run.
            Note that my message is obviously not showing the correct Creation stamp.
            But I don't see that I did anything different/incorrectly. To build that code I did mostly cut&paste, so did very little typing, but nevertheless I've checked the spelling a bunch more times and don't see anything odd. I'm not even going to speculate...

            Can anyone tell what's gone wrong?

            -JohnM
            Last edited by John Montenigro; 9 Dec 2008, 09:58 AM. Reason: reformatted the dates for easier reading

            Comment


              #7
              Code:
              ft.dwLowDateTime = LO(DWORD, FileData.CreationTime)
                 ft.dwHighDateTime = HI(DWORD, FileData.CreationTime)
              The declaration of DIRDATA treats the filetimes as signed integers (QUADs).

              However I will bet you a LOT of money they are actually FILETIME structures.

              Using LO/HI here may be messing you up.

              If you pass BYVAL VARPTR ( DIRDATA.timemember) and tell your function the parameter is a BYREF FILETIME I'll bet it works correctly.

              Alternately you can assign the data to your 'ft as filetime' working variable with:
              Code:
              LOCAL pFT AS FILETIME PTR 
              
                   pFT = VARPTR (DIRDATA_VAR.filetime_Member) ' point at (suspected) FILETIME struct 
                   ft    = @pFT                                         ' assign to working var
                   CALL Datefunction (ft)                            ' ta-dah!
              There are some steps in there which are not necessary but I wanted to show the concept. eg you don't really need the working "Ft" var if your function uses BYREF FILETIME parameter... this is just the 'VARPTR' thing in a slightly different format not requiring an override at the point of call:

              Code:
               LOCAL  pFT  AS FILETIME PTR 
               
                  pFT =    VARPTR(Dirdata_var.Filetime_member) 
                 CALL      DateFunction (@pFT) 
              
              ..
              FUNCTION DateFunction ([BYREF] ft AS FILETIME) AS STRING...
              ...
              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


                #8
                First of all, I changed the settings in Windows Explorer to display all three dates. So I have confirmation that the Creation stamp shown in my earlier post is correct: 2008-11-25 19:15:04


                Originally posted by Michael Mattias View Post
                ...I will bet you a LOT of money they are actually FILETIME structures.

                ...If you pass BYVAL VARPTR ( DIRDATA.timemember) and tell your function the parameter is a BYREF FILETIME I'll bet it works correctly.
                Michael,

                Your supposition appears to be correct. After making the following changes:
                Code:
                      Local FT As FileTime
                      Local pFT As FileTime Ptr
                      pFT = VarPtr (FileData.CreationTime)
                      FT  = @pFT
                      m2$ =       "Creation stamp:    " & GetFileDateTime(FT) & $CrLf      '
                
                      pFT = VarPtr (FileData.LastWriteTime)
                      FT  = @pFT
                      m2$ = m2$ & "LastWrite stamp:   " & GetFileDateTime(FT) & $CrLf      '
                
                      pFT = VarPtr (FileData.LastAccessTime)
                      FT  = @pFT
                      m2$ = m2$ & "LastAccess stamp:  " & GetFileDateTime(FT)              'sometime during this process
                I was able to display three file datestamps:
                Code:
                Creation stamp:    2008-12-09 09:57:22
                LastWrite stamp:   2008-11-25 19:15:05
                LastAccess stamp:  2008-12-09 09:57:22
                However, the same problem is evident: the Creation stamp is incorrect; it should show as: 2008-11-25 19:15:04

                Thnking there could be something in the GetFileDateTime() function that is interfering with the retrieval of the Creation stamp, I re-checked the syntax of the calls, and found this description of the second param of FileTimeToLocalFileTime: "Points to a FILETIME structure to receive the converted local file time. This parameter cannot be the same as the lpFileTime parameter. " So I created a Local FT var and substituted it into the calls, but the result was the same - wrong Create stamp.


                I'm wondering if I'm having an OS interference problem? (WinXP Pro SP3), or maybe I'm not using the correct names for DIRDATA members?

                What else can I test in order to narrow this down?

                Comment


                  #9
                  However I will bet you a LOT of money they are actually FILETIME structures.
                  I would say that is very likely correct.

                  Using LO/HI here may be messing you up.
                  There is no reason why this would be messing you up here. FILETIME structure is 2 DWORD values - no reason you can't retrieve them from the QUAD using HI/LO. The pointer code works for me as well though.

                  There is definitely more than one way you can transition that QUAD into the FILETIME structure. You can use an 8 byte string and use MKQ$ and TYPE SET in a 2 step process to get into the FILETIME structure.

                  The original code by using a UNION is likely the fastest method to get the QUAD number into a FILETIME structure. I was just proposing an alternative not having to use an extra UNION definition.
                  Adam Drake
                  PowerBASIC

                  Comment


                    #10
                    But what about not getting the correct the Create stamp?

                    Comment


                      #11
                      There is no reason why this would be messing you up here. FILETIME structure is 2 DWORD values - no reason you can't retrieve them from the QUAD using HI/LO. The pointer code works for me as well though
                      The problem might be occurring if you try to assign a "LO/HI" 32 bits with bit 31 set to a DWORD target. If you don't "type" the LO/HI, the compiler may be treating the intermediate value (the LO/HI) as a signed LONG and losing bit 31 when assigning to a DWORD target.... Or vice-versa, not being able to assign a DWORD intermediate value with bit 31 set to a LONG target because it will overflow.

                      Inline expresssions are handy, but there can be side effects from "the stuff the compiler does you never see."

                      The pointer method (either using a 'FILETIME PTR' variable or doing a point-of-call override 'BYVAL VARPTR') will always work, because the targets of pointer variables are "type-agostic" other than size of target until an assignment or arithmetic operation is performed.


                      MCM
                      Last edited by Michael Mattias; 9 Dec 2008, 10:57 AM.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                        #12
                        Originally posted by Michael Mattias View Post
                        There is no reason why this would be messing you up here. FILETIME structure is 2 DWORD values - no reason you can't retrieve them from the QUAD using HI/LO. The pointer code works for me as well though

                        The problem will occur if you try to assign a "LO/HI" 32 bits to with bit 31 set to a DWORD target. If you don't "type" the LO/HI, the compiler may be treating the intermediate value as a signed LONG and losing bit 31 when assigning to a DWORD target.... Or vice-versa, not being able to assign a DWORD with bit 31 set to a LONG target because it will overflow.
                        But then, wouldn't all three dates come back equally messed up?

                        It's only the Creation stamp that's coming back wrong, and it's coming back consistently with the LastAcess stamp...

                        Comment


                          #13
                          But then, wouldn't all three dates come back equally messed up?
                          They would.

                          Try an API version of the code and see if you get similar results. If so - then, I would lay the blame on Microsoft:

                          Code:
                          #COMPILE EXE
                          #DIM ALL
                          
                          #INCLUDE "WIN32API.INC"
                          
                          FUNCTION GetFileDateTime(dt AS FILETIME) AS STRING
                          
                              LOCAL lpsystime AS SYSTEMTIME
                              LOCAL szDate    AS ASCIIZ * 64 ' date buffer, %LDT_SIZE = 64 bytes
                              LOCAL szTime    AS ASCIIZ * 64 ' time buffer, %LDT_SIZE = 64 bytes
                          
                              'convert given date to correct format
                              CALL FileTimeToLocalFileTime(dt, dt)
                              CALL FileTimeToSystemTime(dt, lpsystime)
                          
                              CALL GetDateFormat(%LOCALE_USER_DEFAULT, %NULL, lpsystime, "yyyy'-'MM'-'dd", szDate, SIZEOF(szDate))
                          
                              CALL GetTimeFormat (%LOCALE_USER_DEFAULT, %TIME_FORCE24HOURFORMAT, lpsystime, "HH':'mm':'ss" , szTime, SIZEOF(szTime))
                          
                              FUNCTION = szDate & $SPC & szTime
                          
                          END FUNCTION
                          
                          FUNCTION PBMAIN () AS LONG
                          
                              LOCAL SH    AS DWORD
                              LOCAL fSpec AS ASCIIZ * %MAX_PATH
                              LOCAL WFD   AS WIN32_FIND_DATA
                              LOCAL mbTxt AS STRING
                              
                              fSpec = "C:\PBWIN80" ' Insert Folder Name Here
                              
                              SH = FindFirstFile(fSpec, WFD)
                              IF SH <> %INVALID_HANDLE_VALUE THEN
                                  FindClose SH
                                  IF (WFD.dwFileAttributes AND %FILE_ATTRIBUTE_DIRECTORY) = %FILE_ATTRIBUTE_DIRECTORY THEN ' Make Sure it's a folder
                                      mbTxt = "Creation Time: " & $TAB & GetFileDateTime(WFD.ftCreationTime) & $CRLF
                                      mbTxt = mbTxt & "Last Write Time: " & $TAB & GetFileDateTime(WFD.ftLastWriteTime) & $CRLF
                                      mbTxt = mbTxt & "Last Access Time: " & $TAB & GetFileDateTime(WFD.ftLastAccessTime) & $CRLF
                                      MSGBOX mbTxt
                                  END IF
                              END IF
                          
                          END FUNCTION
                          Adam Drake
                          PowerBASIC

                          Comment


                            #14
                            Tried your API code and...

                            got the same (incorrect) result - the Create stamp is showing the LastAccess stamp (during the current run of the program)...

                            SO, now the question is: why can I see the proper Create stamp in Windows Explorer and zTreeWin, but not with API calls???

                            Comment


                              #15
                              Copied from "where?"
                              Not all file systems can record creation and last access time and not all file systems record them in the same manner. For example, on NT FAT, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of 1 day (really, the access date). On NTFS, access time has a resolution of 1 hour. Therefore, the GetFileTime function may not return the same file time information set using the SetFileTime function. Furthermore, FAT records times on disk in local time. However, NTFS records times on disk in UTC. For more information, see File Times.
                              Also
                              File Times and Daylight Saving Time

                              You must take care using file times if the user has set the system to automatically adjust for daylight saving time.

                              To convert a file time to local time, use the FileTimeToLocalFileTime function. However, FileTimeToLocalFileTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, it will take daylight saving time into account, even if the file time you are converting is in standard time.
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                                #16
                                MCM,

                                Yeah, I read that in the SDK help early this morning, when I started questioning the API calls in the GetFileDateTime() routine, and I posted message #8 in this thread at 10:54am...

                                The quoted text describes differences between operating systems. But this is all on one system: XP Pro SP3.

                                The files were originally downloaded and stored on the same hard drive, are residing in the same subdir where they were originally stored. There are no system differences in play here. (Except maybe from SP2 to SP3???)

                                Recap: I can see a valid Create stamp under some tools and Windows Explorer, but not with these API calls.

                                You're not trying to tell me that you might be able to Set but not Get the dates ON THE SAME SYSTEM?? (I could understand that between systems, but it never occurred to me that there could be such an incompatibility on the SAME system!)

                                Comment


                                  #17
                                  I am just reaching for anything which would explain your output.

                                  You're sure you did not open that file for output in your program before you called this, right? (code not shown)... since that would also explain your output, unless all your data were taken at the same time, AFTER the program ran (not stated), in which case you have a genuine mystery.
                                  Michael Mattias
                                  Tal Systems (retired)
                                  Port Washington WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                    #18
                                    Aw cr*p!

                                    Can anyone tell what's gone wrong?
                                    Answer: Yeah, it would appear to be the programmer... :dang:


                                    I spent the afternoon reading up on Registry group policies to see if there was any operating system restrictions in place, etc.

                                    Took a break to take kids to music lessons and napped in the car.

                                    Came back, reviewed code again, and saw something horrible:

                                    The file (the one that I've been checking with Windows Explorer and zTree) is in subdir "\A" (I wish it were that simple - the path is 165 chars long...)

                                    A backup copy of that file is in "\A\backups". (yeah, you've already figured it out)

                                    With the unsurpassed intelligence of a bag of hammers, I managed to copy the path to the backup into my tests. It never jumped out at me.

                                    It was in my post-nap review that I accidentally checked (through zTree) the file info of the backup copy, saw the "incorrect" date, and recognized the combination of errors - the copy and the original are NOT the same! I've been testing on the copy, and FileCopy must not preserve the CreationDate!

                                    Now before you start hitting me with sharp pointy objects, let me mention that I admit my mistake, and I apologize for presenting you with a problem of my own making - but I honestly didn't connect what I was seeing with the copied file.

                                    Under the FileCopy statement (yes I RTFM before I coded the FileCopy section), the Helpfile says "The attributes of the source file are inherited by the destination file, with the exception of the Archive attribute, which is always set ON for the destination file." I've never messed with filedates other than the one available in DOS, so I thought the copy was identical to the original (except for the attribute).

                                    I most humbly apologize for this infuriatingly frustrating diversion, and I thank you for your help. Indeed, it has felt like an impenetrable "mystery" to me.

                                    However, I have now learned about 10 new ways to do things, I have a much better grasp of the various API calls for date and time conversion, and I got a much-needed nap. (I don't know what I'm going to do with all that doubletalk about group policies that I read...)

                                    Now I'm looking forward to a few days of removing all my test/debug code...

                                    But first, I'm shutting down and going to watch some football. Then I'm going to get a good night's sleep.

                                    Next tidbit for the Beginner's Wiki: "Put your hands in the air and step away from the keyboard."

                                    Sincerely - thanks for your help,
                                    -JohnM

                                    Comment


                                      #19
                                      I had a need for some Date/Time code and found this thread. Fooled around with it today and came up with this. Nothing different really, just added a lot of comments, moved things around a little. Thought some newbies/dumbies (like myself) might be interested.

                                      '
                                      Code:
                                      'http://www.powerbasic.com/support/pbforums/showthread.php?t=39304
                                      'Adam Drake
                                      
                                      'Code:
                                      #Compile Exe
                                      #Dim All
                                      #Include "win32api.inc"
                                      '    File Access Time
                                      ' *******************************************************
                                      ' Note to me - see C:\Only_My_Programs\Demos\Date_Time.bas for details
                                      '                                                       
                                      ' Sample call --- Snd$ = z_Date_File_Dates(File_Flag, File_Name$)       
                                      ' found at:
                                      ''http://www.powerbasic.com/support/pbforums/showthread.php?t=39304
                                      '
                                      Function z_Date_File_Dates(Flag As Long, fle As String) As String
                                          'Flag = 1 'created
                                          'Flag = 2 'Last accessed
                                          'Flag = 3 'Last Written to
                                          'Flag = 4 'All of above  
                                         Local FileData As DIRDATA
                                      'TYPE DirData
                                      '  FileAttributes        As Dword
                                      '  CreationTime          As Quad
                                      '  LastAccessTime        As Quad
                                      '  LastWriteTime         As Quad
                                      '  FileSizeHigh          As Dword
                                      '  FileSizeLow           As Dword
                                      '  Reserved0             As Dword
                                      '  Reserved1             As Dword
                                      '  FileName              As Asciiz * 260
                                      '  ShortName             As Asciiz * 14
                                      'End Type  
                                       '
                                         Local ft       As FILETIME
                                      ' Type FILETIME
                                      '  dwLowDateTime As Dword
                                      '  dwHighDateTime As Dword
                                      'End Type
                                       '
                                         Local ln, fnum As Long
                                         Local s, m, ct, la, lwt As String
                                      '   
                                         'now access it without writing to it for testing
                                      '   fnum = FreeFile
                                      '   Open fle$ For Binary As #fnum
                                      '   ln = Lof(#fnum)
                                      '   s$ = Space$(ln)
                                      '   Get #fnum, 1, s$ 
                                      '   'put #fnum, 1, s$ 'see write work
                                      '   Close #fnum 
                                         
                                      'DIR$ equates
                                      '%NORMAL = 0
                                      '%HIDDEN = 2
                                      '%SYSTEM = 4
                                      '%VLABEL = 8
                                      '%SUBDIR = 16
                                         fle$ = Dir$(fle$, %SUBDIR, To FileData) & $CrLf ' fill filedata type with results from fle$
                                      '   
                                         ft.dwLowDateTime = Lo(Dword, FileData.CreationTime)
                                         ft.dwHighDateTime = Hi(Dword, FileData.CreationTime)
                                          ct$ =   "       Created = " & z_Date_GetFileDateTime(ft)
                                      '
                                         ft.dwLowDateTime = Lo(Dword, FileData.LastAccessTime)
                                         ft.dwHighDateTime = Hi(Dword, FileData.LastAccessTime)
                                          la$ = "  Last Accessed = " & z_Date_GetFileDateTime(ft)
                                          
                                         ft.dwLowDateTime = Lo(Dword, FileData.LastWriteTime)
                                         ft.dwHighDateTime = Hi(Dword, FileData.LastWriteTime)
                                          lwt$ = "Last Written To = " & z_Date_GetFileDateTime(ft)
                                      '
                                         Select Case Flag
                                           Case 1 'creation 
                                             Function = ct$
                                           Case 2 'Last Accessed
                                             Function = la$
                                           Case 3 'Last Written
                                             Function = lwt$
                                           Case 4 'all
                                           Function = ct$ & $CrLf & _
                                           la$ & $CrLf & _
                                           lwt$ & $CrLf
                                         End Select  
                                         
                                      End Function   
                                      '
                                      Function z_Date_GetFileDateTime(dt As FILETIME) As String
                                          Local lpsystime As SYSTEMTIME
                                      'TYPE SYSTEMTIME
                                      '  wYear As Word
                                      '  wMonth As Word
                                      '  wDayOfWeek As Word
                                      '  wDay As Word
                                      '  wHour As Word
                                      '  wMinute As Word
                                      '  wSecond As Word
                                      '  wMilliseconds As Word
                                      'End Type
                                      '    
                                          Local szDate    As Asciiz * 64 ' date buffer, %LDT_SIZE = 64 bytes
                                          Local szTime    As Asciiz * 64 ' time buffer, %LDT_SIZE = 64 bytes
                                      '
                                          'convert given date to correct format
                                          Call FileTimeToLocalFileTime(dt, dt)
                                          Call FileTimeToSystemTime(dt, lpsystime)
                                      '
                                      '' Date Flags for GetDateFormat.
                                      '%DATE_SHORTDATE        = &H00000001  ' use short date picture
                                      '%DATE_LONGDATE         = &H00000002  ' use long date picture
                                      '%DATE_USE_ALT_CALENDAR = &H00000004  ' use alternate calendar (if any)
                                      '%DATE_YEARMONTH        = &H00000008  ' use year month picture
                                      '%DATE_LTRREADING       = &H00000010  ' add marks for left to right reading order layout
                                      '%DATE_RTLREADING       = &H00000020  ' add marks for right to left reading order layout
                                          'include day of week ddd or dddd
                                          Call GetDateFormat(%LOCALE_USER_DEFAULT, %Null, lpsystime, "dddd'-'MM'-'dd'-'yyyy'", szDate, SizeOf(szDate))
                                      '                                            
                                      '' Time Flags for GetTimeFormat.
                                      '%TIME_NOMINUTESORSECONDS = &H01   ' do not use minutes or seconds
                                      '%TIME_NOSECONDS          = &H02   ' do not use seconds
                                      '%TIME_NOTIMEMARKER       = &H04   ' do not use time marker
                                      '%TIME_FORCE24HOURFORMAT  = &H08   ' always use 24 hour format
                                      '
                                          Call GetTimeFormat (%LOCALE_USER_DEFAULT, %TIME_FORCE24HOURFORMAT, lpsystime, "HH':'mm':'ss" , szTime, SizeOf(szTime))
                                      '
                                          Function = szDate & $Spc & szTime
                                      '
                                      End Function
                                      '
                                      ' *******************************************************
                                      '
                                      '
                                      Function PBMain () As Long     
                                        Local file_Flag As Long, File_Name, snd, s As String
                                        File_flag = 4
                                      '>>>>>>> change next to suit
                                        File_Name$ = "C:\Only_My_Programs\EasyTape\test01.Swl"
                                        S$ =  File_Name$
                                        Snd$ = z_Date_File_Dates(File_Flag, File_Name$)       
                                        ?snd$,, s$
                                      End Function
                                      '
                                      ==============================================================
                                      "Everything that can be invented has been invented."
                                      Charles H. Duell, Commissioner, U.S. Office of Patents, 1899
                                      ==============================================================
                                      It's a pretty day. I hope you enjoy it.

                                      Gösta

                                      JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                                      LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                                      Comment


                                        #20
                                        The GetDateFormat and GetTimeFormat can come in real handy if you want to 'do something' with dates when you have to support multiple users with different "system default" settings.

                                        Then again, DATE$ and TIME$ always come in the same format, too.

                                        Here's another use of these functions...
                                        SQL Escaped Date, Time, Timestamp functions Demo

                                        .. and just last week I needed to make up a format MS-Access would understand...in this case I needed to put "first of current month" into an SQL statement...
                                        Code:
                                        ' Get String version of 'first of this month'   for inclusion in query
                                          GeTLocalTime      ST      ' get me "today"
                                          ST.wDay         = 1??     ' set to first of this month
                                          szDF            = "'#'yyyy'-'MM'-'dd'#'"   ' Access DB format.
                                          GetDateFormat    %LOCALE_SYSTEM_DEFAULT, BYVAL %NULL, ST, szDF, [COLOR="magenta"]szDFFOM[/COLOR], SIZEOF(szDFFOM)-1
                                        ...
                                        
                                           sSql(iqScPrev)   =   _  
                                             "Select SUM(fin_crg_amount) from cred_fin_crg where cust_no = ?  and fin_crg_date < " & [COLOR="magenta"]szDFFoM[/COLOR]
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎