● 作成・更新・アクセス日時を取得する ●

ま、あまり使い道はないけど知っておいても損はないよ。ファイル更新日比較等で使えるかも。

ファイルの作成・更新・アクセス日時を取得ってすんなりいかないんだよね。ファイルタイムといってもいろいろフォーマットが決まっていて、いろいろと変換するというステップを踏まないといけない。これらの変換処理はVisual Basicでは提供されておらず、API関数を使用しなければならない。変換はファイルタイム→ローカルタイム→システムタイムという手順を踏む。各フォーマットは以下の通り。

ファイルタイム … 1601年1月1日より100ナノ秒間隔でカウントされている(64ビットで保持)
ローカルタイム … コントロールパネルで設定してあるタイムゾーンに基く
システムタイム … ハードディスクに内蔵されている時計に基く

それでは関数を書いてみましょう。

'日付と時刻を定義する構造体
Private Type SYSTEMTIME
      wYear As Integer
      wMonth As Integer
      wDayOfWeek As Integer
      wDay As Integer
      wHour As Integer
      wMinute As Integer
      wSecond As Integer
      wMilliseconds As Integer
End Type

'ファイルタイム
Private Type FILETIME
      dwLowDateTime As Long
      dwHighDateTime As Long
End Type

'ファイルハンドルを取得する
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

'ファイルハンドルを閉じる
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'ファイルタイムを取得する
Private Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long

'世界協定時刻形式ファイル時間をローカルファイル時間に変換する
Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpFileTime As FILETIME, lpLocalFileTime As FILETIME) As Long

'ファイル時間をシステム時間に変換する
Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long

Private Const GENERIC_READ = &H80000000
Private Const OPEN_EXISTING = 3

'---------------------------------------------------------------
'  関数名: GetVariousFileTime
'  機能  : ファイルから作成・更新・アクセス日時を取得する
'  引数  : (in) srcFilePath … ファイルフルパス
'           (in/out) MadeDate … 作成日時
'           (in/out) UpdateDate … 更新日時
'           (in/out) AccessDate … アクセス日時
'  返り値 : なし
'---------------------------------------------------------------
Public Sub GetVariousFileTime(ByVal srcFilePath As String, _
                                    ByRef MadeDate As String, _
                                    ByRef UpdateDate As String, _
                                    ByRef AccessDate As String)

    Dim hFile As Long            'ファイルのハンドル
    Dim udtMadeFileDate As FILETIME    'ファイルが作成された日時を格納
    Dim udtUpdateDate As FILETIME      '最後に更新された日時を格納
    Dim udtAccessDate As FILETIME      '最後にアクセスされた日時を格納
    Dim udtSysMadeFileDate As SYSTEMTIME  'ファイルが作成された日付と時刻を格納
    Dim udtSysUpdateDate As SYSTEMTIME    '最後に更新された日付と時刻を格納
    Dim udtSysAccessDate As SYSTEMTIME    '最後にアクセスされた日付と時刻を格納
    Dim retTime As Long

    'ファイルハンドルを取得する
    hFile = CreateFile(srcFilePath, GENERIC_READ, 0&, 0&, OPEN_EXISTING, 0&, 0&)

    'ファイルタイムを取得する
    retTime = GetFileTime(hFile, udtMadeFileDate, udtAccessDate, udtUpdateDate)

    If retTime Then
          'ファイル作成された日付と時刻を取得する
          Call FileTimeToLocalFileTime(udtMadeFileDate, udtMadeFileDate)
          Call FileTimeToSystemTime(udtMadeFileDate, udtSysMadeFileDate)

          With udtSysMadeFileDate
                MadeDate = .wYear & "年" & _
                            .wMonth & "月" & _
                            .wDay & "日" & _
                            " (" & _
                            Mid$("日月火水木金土", .wDayOfWeek + 1, 1) & _
                            ") " & _
                            .wHour & "時" & _
                            .wMinute & "分" & _
                            .wSecond & "秒"
          End With

          'ファイル更新された日付と時刻を取得する
          Call FileTimeToLocalFileTime(udtUpdateDate, udtUpdateDate)
          Call FileTimeToSystemTime(udtUpdateDate, udtSysUpdateDate)

          With udtSysUpdateDate
                UpdateDate = .wYear & "年" & _
                            .wMonth & "月" & _
                            .wDay & "日" & _
                            " (" & _
                            Mid$("日月火水木金土", .wDayOfWeek + 1, 1) & _
                            ") " & _
                            .wHour & "時" & _
                            .wMinute & "分" & _
                            .wSecond & "秒"
          End With

          'ファイルにアクセスされた日付と時刻を取得する
          Call FileTimeToLocalFileTime(udtAccessDate, udtAccessDate)
          Call FileTimeToSystemTime(udtAccessDate, udtSysAccessDate)

          With udtSysAccessDate
                AccessDate = .wYear & "年" & _
                            .wMonth & "月" & _
                            .wDay & "日" & _
                            " (" & _
                            Mid$("日月火水木金土", .wDayOfWeek + 1, 1) & _
                            ")"
          End With

    End If

    'ファイルハンドルを閉じる
    Call CloseHandle(hFile)

End Sub

以下のコードをお試しあれ

Private Sub Command1_Click()

    Dim MadeDate As String
    Dim UpdateDate As String
    Dim AccessDate As String

    Call GetVariousFileTime(Environ("WINDIR") & "\Winhlp32.ini", MadeDate, UpdateDate, AccessDate)

    Debug.Print "作成日時 : " & MadeDate
    Debug.Print "更新日時 : " & UpdateDate
    Debug.Print "アクセス日時 : " & AccessDate

End Sub

ファイルが更新された日付を取得するだけであれば、FileDateTime 関数を使用した方がいいかも。これは Visual Basic の関数だから安心して使える。詳しくはヘルプを見てね。


戻る