【Python】ファイルとフォルダのタイムスタンプを変更するコード例【作成日時・更新日時・アクセス日時を変更する】

Pythonパイソン から PowerShellパワーシェル を呼び出して、『ファイルとフォルダ』の『作成日時さくせいにちじ更新日時こうしんにちじ・アクセス日時にちじ』を変更するコード例です。

フォルダを指定して、その中にある『ファイルとフォルダ』の『タイムスタンプ』を、一括いっかつで変更します。

※ PowerShell を使わずに、Python の外部ライブラリで変更する方法は、『ファイルのタイムスタンプを変更するコード例』に書きました。

タイムスタンプの変更方法

Python のサブプロセスラン subprocess.run(cmd) から、PowerShellパワーシェル を呼び出して、タイムスタンプを変更します。

以下は、コマンドラインから PowerShell を起動して、普通にタイムスタンプを変更するコマンド例です。

F:\apps\data>PowerShell -Version 5.1
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS F:\apps\data> Get-ChildItem -LiteralPath F:\\apps\\data -Recurse -Force | ForEach-Object { Set-ItemProperty -LiteralPath $_.FullName -Name Attributes -Value Normal ; Set-ItemProperty -LiteralPath $_.FullName -Name CreationTime -Value "2017/01/02 03:04:05" ; Set-ItemProperty -LiteralPath $_.FullName -Name LastWriteTime -Value "2018/01/02 03:04:05" ; Set-ItemProperty -LiteralPath $_.FullName -Name LastAccessTime -Value "2019/01/02 03:04:05" ; }

これと同じことを、Python で指示して、実行するアプローチになります。

『作成日時・更新日時・アクセス日時』を変更するための PowerShell コマンドは、コマンドライン文字列のリスト (cmd) として、用意します。

cmdシーエムディー は、Python のリスト (list) です。タプル (tuple) を使っても OK でした。

cmd の中に『タイムスタンプを変更する PowerShell コマンド』を書きます。

これを subprocess.run(cmd) に渡して実行することで、ファイルとフォルダのタイムスタンプを変更することができました。

Python マニュアル

使用した Pythonパイソン ライブラリの公式マニュアルの場所です。

subprocess — サブプロセス管理

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None) サブプロセスラン

class subprocess.CompletedProcess コンプリーテッドプロセス(argsアーグス, returncodeリターンコード, stdoutエスティーディーアウト, stderrエスティーディーイーアールアール などが取得できる)

pathlib — オブジェクト指向のファイルシステムパス パスリブ

class pathlib.Path(*pathsegments) パス

Path.glob(pattern) グロブ

Path.stat() スタット

class os.stat_result スタットリザルト(st_atime, st_mtime, st_ctime の説明)

PurePath.name ネーム

datetime — 基本的な日付型および時間型 デートタイム

classmethod datetime.fromtimestamp(timestamp, tz=None) フロムタイムスタンプ

rアール から始まる文字列 r'' は、 raw stringsロウ ストリングス と呼ばれるもの。

文字列型 (string)

文字列およびバイト列リテラル

fエフ から始まる文字列 f'' は、f-stringエフ ストリング とか、フォーマット済み文字列リテラル とか呼ばれるもの。

f-string

フォーマット済み文字列リテラル

組み込み関数

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) プリント

PowerShell マニュアル

使用した PowerShell コマンドの公式マニュアルの場所です。

Microsoft DocsPowerShellOverview

About PowerShell.exe (バージョンを指定して起動するための -Version の説明など)

Get-ChildItem ゲットチャイルドアイテム

Get-ChildItem ⇒ ParametersDirectoryディレクトリ, Fileファイル, Hiddenヒドゥン, ReadOnlyリードオンリー, -LiteralPathリテラルパス, -Recurseリカース, -Forceフォース, などの説明)

ForEach-Object フォーイーチオブジェクト

ForEach-Object ⇒ Description (変数 $_ ダラーアンダースコア、ドルサインアンダースコアの説明)

Set-ItemProperty セットアイテムプロパティ

Set-ItemProperty ⇒ Examples (読み取り専用属性 IsReadOnly の設定例など)

Set-ItemProperty ⇒ Parameters (-LiteralPath, -Name, -Value などの説明)

About PowerShell Editions$PSVersionTableドルサインピーエスバージョンテーブル の説明)

.NET マニュアル

PowerShell コマンドの中で使用した名前(FullNameフルネーム, Attributesアトリビューツ, CreationTimeクリエイションタイム, LastWriteTimeラストライトタイム, LastAccessTimeラストアクセスタイム, IsReadOnlyイズリードオンリー など)の、公式マニュアルの場所です。

これらは、.NETドットネット のマニュアルの中にありました。

Microsoft Docs.NET.NET Core API referenceSystem.IO Namespace

FileInfo Class ファイルインフォ

FileInfo Class ⇒ Properties (FullName, Attributes, CreationTime, LastWriteTime, LastAccessTime, IsReadOnly などの説明)

DirectoryInfo Class ディレクトリインフォ

DirectoryInfo Class ⇒ Properties (FullName, Attributes, CreationTime, LastWriteTime, LastAccessTime などの説明)

コード例

ファイルとフォルダ』のタイムスタンプを変更する Python コード例です。

PowerShell の機能を使って、『作成日時・更新日時・アクセス日時』を変更します。

フォルダパスを指定して、その中にある『ファイルとフォルダ』の両方のタイムスタンプを、すべて変更します。

読み取り専用属性』は、タイムスタンプ変更のさまたげになったので、解除コマンドを入れています。ついでに、『隠しファイル属性』も解除しています。

$_.FullName』には、『ファイルパス または フォルダパス』が、自動的に入ります。

$_ の読み方は、ダラーアンダースコアでした。YouTube で、そう呼んでいる方を見かけました。ドルサインアンダースコアでもいいと思います。

これは、『ForEach-Object』の変数『$_』が持っている『FullName』プロパティを参照しています。

"""
ファイルとフォルダのタイムスタンプを変更するコード例。
Python から Windows の PowerShell を呼び出して、
ファイルとフォルダの作成日時、更新日時、アクセス日時を
変更します。
"""

import subprocess

print('Start')

# (1/4) フォルダを決める
data_dir = r'F:\apps\data'


# (2/4) 日時を決める
creation_time    = '"2017/01/02 03:04:05"' # 作成
last_write_time  = '"2018/01/02 03:04:05"' # 更新
last_access_time = '"2019/01/02 03:04:05"' # アクセス


# (3/4) PowerShellのコマンドを決める
cmd = [
    # PowerShellを指定 (PowerShell 5.1)
    'PowerShell', '-Version', '5.1',

    # フォルダを指定
    'Get-ChildItem',
    '-LiteralPath', data_dir, # 日時変更の対象フォルダ
    '-Recurse', # フォルダのフォルダも変更対象にする
    '-Force', # 隠しファイルも変更対象にする

    # Get-ChildItem の結果を ForEach-Object に渡すための記号
    '|',

    # フォルダの中のファイルとフォルダを、1つずつたどる。
    'ForEach-Object',
    '{',

    # 読み取り専用属性と隠しファイル属性を外す
    'Set-ItemProperty',
    '-LiteralPath', '$_.FullName',
    '-Name', 'Attributes',
    '-Value', 'Normal',
    ';',

    # 作成日時 (ctime) 変更
    'Set-ItemProperty',
    '-LiteralPath', '$_.FullName',
    '-Name', 'CreationTime',
    '-Value', creation_time,
    ';',

    # 更新日時 (mtime) 変更
    'Set-ItemProperty',
    '-LiteralPath', '$_.FullName',
    '-Name', 'LastWriteTime',
    '-Value', last_write_time,
    ';',

    # アクセス日時 (atime) 変更
    'Set-ItemProperty',
    '-LiteralPath', '$_.FullName',
    '-Name', 'LastAccessTime',
    '-Value', last_access_time,
    ';',

    '}',

    # (デバッグ) PowerShellのバージョンを表示する
    ';',
    '$PSVersionTable',
] # cmd ここまで


# (4/4) 実行する
cp = subprocess.run(cmd)

print('End')
# 以上です。

# 以下は、デバッグ用のコードです。
print('\nStart Debug')

# (デバッグ1) 変更結果を確認する
import pathlib
import datetime

data_dir_path = pathlib.Path(data_dir)
print('\n(デバッグ1) 変更結果を確認する')
print('名前 - 作成日時 - 更新日時 - アクセス日時')
for p in data_dir_path.glob('**/*'):
    stat = p.stat()
    ctime = datetime.datetime.fromtimestamp(stat.st_ctime)
    mtime = datetime.datetime.fromtimestamp(stat.st_mtime)
    atime = datetime.datetime.fromtimestamp(stat.st_atime)
    print(f'{p.name} - {ctime} - {mtime} - {atime}')


# (デバッグ2) subprocess.run の戻り値を見る
print('\n(デバッグ2) subprocess.run の戻り値を見る')
print(f'cp = subprocess.run(cmd)')
print(f'cp.returncode: {cp.returncode}')
print(f'cp.stdout: {cp.stdout}')
print(f'cp.stderr: {cp.stderr}')
print('cp.args: %s' % '\n    '.join(cp.args))
# cp: CompletedProcess の略です。

print('\nEnd Debug')

実行結果

Python コードの実行結果です。

『ファイルとフォルダ』の『作成日時・更新日時・アクセス日時』を、すべて変更することができました。

タイムスタンプの変更中は、とくに何も表示されませんでした。

実行結果で表示されたものは、デバッグのために書いた情報だけでした。

Start

Name                           Value
----                           -----
PSVersion                      5.1.14409.1018
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14409.1018
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


End

Start Debug

(デバッグ1) 変更結果を確認する
名前 - 作成日時 - 更新日時 - アクセス日時
memo-01.pdf - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-02.docx - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-03.xlsx - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-04.pptx - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-05.txt - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-06.csv - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-07.odt - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-08.ods - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-09.odp - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-10.html - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-11.css - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
memo-12.js - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
photos - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
image-01.jpg - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
image-02.png - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
image-03.gif - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
image-04.bmp - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05
image-05.webp - 2017-01-02 03:04:05 - 2018-01-02 03:04:05 - 2019-01-02 03:04:05

(デバッグ2) subprocess.run の戻り値を見る
cp = subprocess.run(cmd)
cp.returncode: 0
cp.stdout: None
cp.stderr: None
cp.args: PowerShell
    -Version
    5.1
    Get-ChildItem
    -LiteralPath
    F:\apps\data
    -Recurse
    -Force
    |
    ForEach-Object
    {
    Set-ItemProperty
    -LiteralPath
    $_.FullName
    -Name
    Attributes
    -Value
    Normal
    ;
    Set-ItemProperty
    -LiteralPath
    $_.FullName
    -Name
    CreationTime
    -Value
    "2017/01/02 03:04:05"
    ;
    Set-ItemProperty
    -LiteralPath
    $_.FullName
    -Name
    LastWriteTime
    -Value
    "2018/01/02 03:04:05"
    ;
    Set-ItemProperty
    -LiteralPath
    $_.FullName
    -Name
    LastAccessTime
    -Value
    "2019/01/02 03:04:05"
    ;
    }
    ;
    $PSVersionTable

End Debug

変更結果の画像

タイムスタンプ変更前

すべてのファイルには、『読み取り専用属性』が付いていました。

photosフォトス フォルダの中には、さらに、画像ファイルの image-01.jpg ~ image-05.webpウェッピー が入っていました。

また、photo フォルダと、その中のファイルには、『隠しファイル属性』が付いていました。

変更後

ファイルのプロパティ

意図した通り、フォルダの中にある『ファイルとフォルダ』の『作成日時・更新日時・アクセス日時』を、すべて変更することができました。

自分の場合は、『読み取り専用属性』と『隠しファイル属性』が不要でした。

なので、コード例では、それらを外すために -Name Attributes で -Value Normal を指定しました。

タイトルとURLをコピーしました