

`os.stat`の`st_mtime`だとコピーした時点の時刻に変わってしまうようです。エクスプローラの表示と同じ更新時刻を取得する方法はないのでしょうか。

* * *

追記：

作業の更新比較を行いたいので、エクスプローラの表示と同じ更新時刻を取得したいのです。

仰るとおり更新時刻の情報を保持したままコピーできればよいのですが、非エンジニアがファイル整理などを行うこともあるのでどうしても全てPythonのコマンドで、とはいきません。そういった場合でもエクスプローラで表示される更新時刻は作業時点の更新時刻に保たれているので、これを取得したかったのです。

個人的にも調べてみたところNTFSのFile Modified Time
(ATime)がこれにあたるようなのですが、取得する方法が見当たらない、といった状況です。

Python | タイムスタンプ種別(NTFS) | 説明(NTFS)  
---|---|---  
st_ctime | File Create Time (CTime) | ファイルが作成された時間。  
 **エクスプローラで表示される作成日時**  
| File Modified Time (ATime) | ファイルのデータが更新された時間。  
 **エクスプローラで表示される更新日時**  
st_mtime | MFT Entry modified Time (MTime) | このMFTエントリが更新された日時  
ファイルデータ、ファイル名、ファイル属性、セキュリティ情報、所有者などMFT内のどの情報を更新してもタイムスタンプが更新される  
st_atime | File Last Access Time (RTime) | **エクスプローラで表示されるアクセス日時**


CC BY-SA 4.0
2021-04-19T06:38:10.963
75375
2021-04-20T23:21:13.283
2021-04-20T23:21:13.283
44899
44898
question
python windows
Windowsでファイルの更新時刻（エクスプローラの表示と同じ）を取得したい


stackoverflow.comでの類似質問への回答  
<https://stackoverflow.com/a/38524858/4366193>

この回答ではWin32APIを直接呼び出して、ファイルの属性情報を取得しているようです。(Windows OS依存のPythonコードになります)

Windows 10 (64bit), Python 3.9.4 で確認を行いました。

[code]

    Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    
    >>> from ctypes import windll, Structure, byref
    >>> from ctypes.wintypes import LPWSTR, DWORD, FILETIME
    >>>
    >>> class WIN32_FILE_ATTRIBUTE_DATA(Structure):
    ...     _fields_ = [("dwFileAttributes", DWORD),
    ...                 ("ftCreationTime", FILETIME),
    ...                 ("ftLastAccessTime", FILETIME),
    ...                 ("ftLastWriteTime", FILETIME),
    ...                 ("nFileSizeHigh", DWORD),
    ...                 ("nFileSizeLow", DWORD)]
    ...
    >>> filename = 'D:\\test.csv'
    >>>
    >>> wfad = WIN32_FILE_ATTRIBUTE_DATA()
    >>> GetFileExInfoStandard = 0
    >>> windll.kernel32.GetFileAttributesExW(LPWSTR(filename), GetFileExInfoStandard, byref(wfad))
    1
    >>> lowtime = wfad.ftLastWriteTime.dwLowDateTime
    >>> hightime = wfad.ftLastWriteTime.dwHighDateTime
    >>> filetime = (hightime << 32) + lowtime
    >>> print(filetime)
    132003113268921297
    
[/code]

ただし、取得できるデータは`FILETIME構造体`になるので、Unix epoch timeへの変換などを行わないと使いづらいかと思います。

<https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-
filetime>  
<https://docs.microsoft.com/ja-
jp/dotnet/api/system.runtime.interopservices.comtypes.filetime?view=net-5.0>

> FILETIME 構造体
>
> 1601 年 1 月 1 日以降の 100 ナノ秒間隔の数を表します。 この構造体は 64 ビット値です。

例えば、以下のサイトを参考に変換すればEpoch secondsが得られます。  
(ちなみにanalyzeMFTでも[似たような処理](https://github.com/dkovar/analyzeMFT/blob/79a33cedc3b3817dec80be49e51a18699a00d39f/analyzemft/mftutils.py#L38-L44)を行っているようです)

<https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/>

> Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds, so we
> will just subtract that value
[code]

    >>> diff = filetime - (11644473600000 * 10000)
    >>> epoch = diff / 10000000
    >>> print(epoch)
    1555837726.8921297
    
[/code]

<https://www.epochconverter.com/> で確認を行うと以下の様になります。

> GMT: 2019年4月21日 Sunday 09:08:46  
>  Your time zone: 2019年4月21日 日曜日 18:08:46 GMT+09:00

**Explorerでのスクリーンショット**

[![画像の説明をここに入力](https://i.stack.imgur.com/pW1mD.png)](https://i.stack.imgur.com/pW1mD.png)


CC BY-SA 4.0
2021-04-20T17:03:56.090
75414
2021-04-20T18:04:23.853
2021-04-20T18:04:23.853
3068
3068
75375
answer