How do I change the file creation date of a Windows file from Python?
-
5*modification*, *access* times could be changed by `os.utime()` http://docs.python.org/library/os.html#os.utime – jfs Feb 14 '11 at 19:43
-
@Sebastian: thanks for the links. i looked at the SO questions, they said there no platform-independent way to do it as for example linux doesn't store file creation times – Claudiu Feb 14 '11 at 19:49
-
@David: hah nice, i'll remember that. what do you do for comments? – Claudiu Feb 14 '11 at 20:25
-
@Claudiu: I've posted it for readers who search google for `"python change file date windows"`. Your question is the second link. – jfs Feb 15 '11 at 23:37
-
2Same question for Linux: http://stackoverflow.com/q/887557/321973 – Tobias Kienzler Dec 15 '14 at 14:03
12 Answers
Yak shaving for the win.
import pywintypes, win32file, win32con
def changeFileCreationTime(fname, newtime):
wintime = pywintypes.Time(newtime)
winfile = win32file.CreateFile(
fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime(winfile, wintime, None, None)
winfile.close()

- 224,032
- 165
- 485
- 680
-
6If you get an ImportError and wonder where you could find `pywintypes` (as I did): http://sourceforge.net/projects/pywin32/ – netvope Apr 08 '11 at 09:04
-
-
I like this "yak shaving" indeed this feels like what I am trying to do to support the Wintendo operating system. :) – Tomachi Aug 25 '19 at 03:51
-
1`GENERIC_WRITE` requests data access that's not required here and either may not be granted by the file security or may lead to a sharing violation if an existing open doesn't share write-data access. The operation should only request `FILE_WRITE_ATTRIBUTES` metadata access, for which no data-access sharing is required, e.g. `hfile = win32file.CreateFile(fname, ntsecuritycon.FILE_WRITE_ATTRIBUTES, 0, None, win32con.OPEN_EXISTING, 0, None)`. – Eryk Sun Sep 01 '20 at 20:03
I did not want to bring the whole pywin32
/ win32file
library solely to set the creation time of a file, so I made the win32-setctime
package which does just that.
pip install win32-setctime
And then use it like that:
from win32_setctime import setctime
setctime("my_file.txt", 1561675987.509)
Basically, the function can be reduced to just a few lines without needing any dependency other that the built-in ctypes
Python library:
from ctypes import windll, wintypes, byref
# Arbitrary example of a file and a date
filepath = "my_file.txt"
epoch = 1561675987.509
# Convert Unix timestamp to Windows FileTime using some magic numbers
# See documentation: https://support.microsoft.com/en-us/help/167296
timestamp = int((epoch * 10000000) + 116444736000000000)
ctime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32)
# Call Win32 API to modify the file creation date
handle = windll.kernel32.CreateFileW(filepath, 256, 0, None, 3, 128, None)
windll.kernel32.SetFileTime(handle, byref(ctime), None, None)
windll.kernel32.CloseHandle(handle)
For advanced management (like error handling), see the source code of win32_setctime.py
.

- 18,571
- 11
- 90
- 141
-
This code would be more useful if the meanings of the magic numbers were explained. My guesses are: - epoch is time in seconds? Since when? Maybe it doesn't matter? - 10000000 is a conversion factor between seconds and WIndows' 100 ns time units - 116444736000000000 is, well, I have no idea. It seems to be a time span of ~369 years, but I can't really tell. – Bruce Dawson Jan 31 '20 at 22:10
-
1@BruceDawson This comes from the Microsoft documentation: [How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME](https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime). – Delgan Jan 31 '20 at 22:17
-
Thanks. That helps give context to the meaning of some of the magic numbers. It would still be good to document them in your answer, including the still unexplained 1561675987.509 number, which I guess is just a randomly selected time? – Bruce Dawson Feb 02 '20 at 02:39
-
1
-
The project on GitHub should be updated to use `kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)` and raise exceptions via `raise ctypes.WinError(ctypes.get_last_error())`. This (1) isolates it from other packages that use the global library loader `ctypes.windll`, which caches loaded libraries, which cache function pointers, and (2) reliably captures the thread's last error value in C immediately after the FFI call. – Eryk Sun Sep 01 '20 at 20:10
-
Thanks for your suggestion @ErykSun, I will make the update whenever I have some time (otherwise feel free to open a PR). Please, can you explain me why should I explicitly call `ctypes.get_last_error()` while raising a `WinError()`? Reading the documentation, I thought `GetLastError()` was automatically called anyway. – Delgan Sep 01 '20 at 20:40
-
Using ctypes to call `GetLastError()` via FFI leaves a lot of executed code between the original FFI call and the `GetLastError()` FFI call -- since Python is an interpreted scripting language. Loading the DLL with `use_last_error=True` automatically configures all function pointers created from it (e.g. `kernel32.CreateFileW`) to use a thread-local variable to set and capture the value of `GetLastError()` in C before and after the FFI call. `ctypes.get_last_error()` returns this thread-local last error value, and `ctypes.set_last_error(error_code)` sets it. – Eryk Sun Sep 01 '20 at 21:13
-
@ErykSun I think I got it, thanks a lot for the clarification! I will update `win32-setctime` as soon as possible. – Delgan Sep 02 '20 at 06:01
-
My simple and clear filedate
module might accommodate your needs.
Advantages:
- Very simple interface
- Platform independent
- Fancy string dates support
- Date Holder utility
Installation
pip install filedate
Usage
import filedate
Path = "~/Documents/File.txt"
filedate.File(Path).set(
created = "1st February 2003, 12:30",
modified = "3:00 PM, 04 May 2009",
accessed = "08/07/2014 18:30:45"
)

- 147
- 1
- 8
install pywin32 extension first https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/
import win32file
import pywintypes
# main logic function
def changeFileCreateTime(path, ctime):
# path: your file path
# ctime: Unix timestamp
# open file and get the handle of file
# API: http://timgolden.me.uk/pywin32-docs/win32file__CreateFile_meth.html
handle = win32file.CreateFile(
path, # file path
win32file.GENERIC_WRITE, # must opened with GENERIC_WRITE access
0,
None,
win32file.OPEN_EXISTING,
0,
0
)
# create a PyTime object
# API: http://timgolden.me.uk/pywin32-docs/pywintypes__Time_meth.html
PyTime = pywintypes.Time(ctime)
# reset the create time of file
# API: http://timgolden.me.uk/pywin32-docs/win32file__SetFileTime_meth.html
win32file.SetFileTime(
handle,
PyTime
)
# example
changeFileCreateTime('C:/Users/percy/Desktop/1.txt',1234567789)

- 710
- 9
- 11
-
2Why is it so hard to find out that `win32file` is part of `pywin32`? Google left me high and dry, which meant none of the other answers were at all useful; they assumed you already had it installed. Thank you for the helpful hint at the top of your answer. – Mark Ransom Oct 19 '18 at 19:00
-
P.S. Anybody who needs a timestamp from a `datetime` object can find the answer here: https://stackoverflow.com/q/7852855/5987 – Mark Ransom Oct 19 '18 at 19:02
Here's a more robust version of the accepted answer. It also has the opposing getter function. This addresses created, modified, and accessed datetimes. It handles having the datetimes parameters provided as either datetime.datetime objects, or as "seconds since the epoch" (what the getter returns). Further, it adjusts for Day Light Saving time, which the accepted answer does not. Without that, your times will not be set correctly when you set a winter or summer time during the opposing phase of your actual system time.
The major weakness of this answer is that it is for Windows only (which answers the question posed). In the future, I'll try to post a cross platform solution.
def isWindows() :
import platform
return platform.system() == 'Windows'
def getFileDateTimes( filePath ):
return ( os.path.getctime( filePath ),
os.path.getmtime( filePath ),
os.path.getatime( filePath ) )
def setFileDateTimes( filePath, datetimes ):
try :
import datetime
import time
if isWindows() :
import win32file, win32con
ctime = datetimes[0]
mtime = datetimes[1]
atime = datetimes[2]
# handle datetime.datetime parameters
if isinstance( ctime, datetime.datetime ) :
ctime = time.mktime( ctime.timetuple() )
if isinstance( mtime, datetime.datetime ) :
mtime = time.mktime( mtime.timetuple() )
if isinstance( atime, datetime.datetime ) :
atime = time.mktime( atime.timetuple() )
# adjust for day light savings
now = time.localtime()
ctime += 3600 * (now.tm_isdst - time.localtime(ctime).tm_isdst)
mtime += 3600 * (now.tm_isdst - time.localtime(mtime).tm_isdst)
atime += 3600 * (now.tm_isdst - time.localtime(atime).tm_isdst)
# change time stamps
winfile = win32file.CreateFile(
filePath, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime( winfile, ctime, atime, mtime )
winfile.close()
else : """MUST FIGURE OUT..."""
except : pass

- 39
- 7

- 10,221
- 5
- 83
- 96
This code works on python 3 without
ValueError: astimezone() cannot be applied to a naive datetime
:
wintime = datetime.datetime.utcfromtimestamp(newtime).replace(tzinfo=datetime.timezone.utc)
winfile = win32file.CreateFile(
fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime(winfile, wintime)
winfile.close()

- 4,089
- 20
- 25
-
Error using python 3: type object 'datetime.datetime' has no attribute 'datetime' – Vlad Feb 23 '17 at 00:01
-
1@Vlad it's an error using incorrect import statements. The object is datetime.datetime as in my example, not datetime.datetime.datetime as you're trying to use it. – panda-34 Feb 23 '17 at 05:54
-
you're right - I've change the import statement but now the error is `a float is required` for `datetime.datetime.utcfromtimestamp(newtime)`. It would be great to have this work in python 3. – Vlad Feb 23 '17 at 10:05
import os
os.utime(path, (accessed_time, modified_time))
http://docs.python.org/library/os.html
At least it changes the modification time, without using win32 module.

- 137,073
- 23
- 153
- 219

- 2,004
- 3
- 25
- 33
-
21Unfortunately, I'm pretty sure this only changes the file modification time and access time, not the file creation time, as the OP desires. – JJC Feb 21 '12 at 13:41
-
1
-
6Doesn't do anything on XP or Win7 for me, the atime sets accesstime and mtime sets modifiedtime, neither sets creationtime. – SilverbackNet Jul 09 '12 at 17:34
Here is a solution that works on Python 3.5 and windows 7. Very easy. I admit it's sloppy coding... but it works. You're welcome to clean it up. I just needed a quick soln.
import pywintypes, win32file, win32con, datetime, pytz
def changeFileCreationTime(fname, newtime):
wintime = pywintypes.Time(newtime)
winfile = win32file.CreateFile(fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ |
win32con.FILE_SHARE_WRITE |
win32con.FILE_SHARE_DELETE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL,
None)
win32file.SetFileTime( winfile, wintime, wintime, wintime)
# None doesnt change args = file, creation, last access, last write
# win32file.SetFileTime(None, None, None, None) # does nonething
winfile.close()
if __name__ == "__main__":
local_tz = pytz.timezone('Antarctica/South_Pole')
start_date = local_tz.localize(datetime.datetime(1776,7,4), is_dst=None)
changeFileCreationTime(r'C:\homemade.pr0n', start_date )

- 504
- 7
- 17
-
1For directories: see here: https://stackoverflow.com/questions/4998814/createfile-getfiletime-setfiletime ! – Tomasz Gandor Mar 25 '19 at 11:14
If you want to put a date instead of an epoch you can grab this code. I used win32-setctime and attrs packages so firstly install:
pip install win32-setctime
pip install attrs
Then you can run my code, remember to update FILEPATH, DATE, MONTH and YEAR.
from datetime import datetime
import attr
from win32_setctime import setctime
FILEPATH = r'C:\Users\jakub\PycharmProjects\date_creation_change\doc.docx'
DAY, MONTH, YEAR = (9, 5, 2020)
@attr.s
class TimeCounter:
"""
Class calculates epochs
"""
day = attr.ib(converter=str)
month = attr.ib(converter=str)
year = attr.ib(converter=str)
def create_datetime(self):
date_time_obj = datetime.strptime(r'{}/{}/{}'.format(self.day,
self.month,
self.year), '%d/%m/%Y')
unix_start = datetime(1970, 1, 1)
return (date_time_obj - unix_start).days
def count_epoch(self):
days = self.create_datetime()
return days * 86400
@attr.s
class DateCreatedChanger:
"""
Class changes the creation date of the file
"""
file_path = attr.ib()
def change_creation_date(self):
epoch_obj = TimeCounter(day=DAY,
month=MONTH,
year=YEAR)
epoch = epoch_obj.count_epoch()
setctime(self.file_path, epoch)
if __name__ == '__main__':
changer = DateCreatedChanger(FILEPATH)
changer.change_creation_date()

- 61
- 1
- 3
A small solution without dependencies inspired by Delgan's answer.
It supports unix timestamps up to nano precision (like the values returned by os.stat(...).st_ctime_ns
as an example).
Modified, accessed and created timestamps are supported.
Unpassed/noned parameters are being ignored by the Win32 api call (those file properties won't be changed).
It requires python 3.10 for the multi-type hints used on the parameters. Just remove the hints if you want it to work for older python versions.
from ctypes import wintypes, byref, WinDLL, WinError, get_last_error
def __unix_ts_to_win_filetime(self, timestamp: int | None) -> wintypes.FILETIME:
if not timestamp:
return wintypes.FILETIME(0xFFFFFFFF, 0xFFFFFFFF)
# difference in ticks between 16010101 and 19700101 (leapseconds were introduced in 1972 so we're fine)
_EPOCH_OFFSET_TICKS = 116444736000000000
# truncate timestamp to 19 decimals or fill it up with zeroes
timestamp = int(str(timestamp)[:19].rjust(19, '0'))
timestamp_in_ticks = int(timestamp / 100)
# add epoch offset to timestamp ticks
timestamp_in_ticks += _EPOCH_OFFSET_TICKS
# convert to wintypes.FILETIME by filling higher (32-bit masked) and lower number (shifted by 32 bits)
return wintypes.FILETIME(timestamp_in_ticks & 0xFFFFFFFF, timestamp_in_ticks >> 32)
def __set_times_on_file(self, path: str, created_timestamp: int = None, access_timestamp: int = None, modify_timestamp: int = None) -> bool:
created_timestamp = self.__unix_ts_to_win_filetime(timestamp=created_timestamp)
access_timestamp = self.__unix_ts_to_win_filetime(timestamp=access_timestamp)
modify_timestamp = self.__unix_ts_to_win_filetime(timestamp=modify_timestamp)
# Win32 API call for CreateFileW and SetFileTime
kernel32 = WinDLL("kernel32", use_last_error=True)
hndl = kernel32.CreateFileW(path, 256, 0, None, 3, 128, None)
if hndl == -1:
print(WinError(get_last_error()))
return False
if not wintypes.BOOL(kernel32.SetFileTime(hndl, byref(created_timestamp), byref(access_timestamp), byref(modify_timestamp))):
print(WinError(get_last_error()))
return False
if not wintypes.BOOL(kernel32.CloseHandle(hndl)):
print(WinError(get_last_error()))
return False
return True
Usage example
if __set_times_on_file(path='C:\Windows\Temp\foo.bar', created_timestamp=1657101345298000000):
print("file timestamps could be set")
else:
print("file timestamps could not be set")

- 21
- 3
I could not find a straight answer for python exactly, so i am leaving an answer for anyone searching how to modify the dates for a directory (or a file, thanks to the answers in this thread).
import os, win32con, win32file, pywintypes
def changeCreationTime(path, time):
try:
wintime = pywintypes.Time(time)
# File
if os.path.isfile(path):
winfile = win32file.CreateFile(path,
win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ |
win32con.FILE_SHARE_WRITE |
win32con.FILE_SHARE_DELETE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL,
None)
win32file.SetFileTime(winfile, wintime, wintime, wintime)
winfile.close()
print(f'File {path} modified')
# Directory
elif os.path.isdir(path):
windir = win32file.CreateFile(path,
win32con.GENERIC_WRITE,
win32con.FILE_SHARE_WRITE |
win32con.FILE_SHARE_DELETE |
win32con.FILE_SHARE_READ,
None,
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS,
None)
win32file.SetFileTime(windir, wintime, wintime, wintime)
windir.close()
print(f"Directory {path} modified")
except BaseException as err:
print(err)
Example:
# Create a folder named example and a text file named example.txt in C:\example
changeCreationTime(r'C:\example', 1338587789)
changeCreationTime(r'C:\example\example.txt', 1338587789)

- 1
In the answer from Claudiu replace following lines
import pywintypes, win32file, win32con
wintime = pywintypes.Time(newtime)
as follows, in order to change also milliseconds of the file creation
import datetime, win32file, win32conimport
wintime = datetime.datetime.fromtimestamp(newtime)

- 1
- 1