Python code to change modified date for xlsx and docx files
import os
import sys
import tkinter as tk
from tkinter import filedialog
from datetime import datetime
from docx import Document
from openpyxl import load_workbook
from openpyxl.workbook.properties import WorkbookProperties
# -------------------------------
# Platform-specific creation time
# -------------------------------
def set_file_creation_time(filepath, created_dt):
"""
Set file creation time (birth time).
- Linux/macOS: uses os.utime with ns (nanoseconds)
- Windows: NOT SUPPORTED by Python/os — will skip with warning
"""
if sys.platform == "win32":
print("Warning: Changing 'Created' time is NOT supported on Windows via Python.")
print(" Use third-party tools like 'SetFileTime' or PowerShell if needed.")
return False
# Only for macOS and Linux
try:
# Convert to timestamp
timestamp = created_dt.timestamp()
atime = os.stat(filepath).st_atime # keep access time
mtime = timestamp
# Use nanosecond version if available
try:
os.utime(filepath, ns=(int(atime * 1e9), int(mtime * 1e9)))
return True
except AttributeError:
# Fallback to seconds
os.utime(filepath, (atime, mtime))
return True
except Exception as e:
print(f"Failed to set creation time: {e}")
return False
# -------------------------------
# Helper Functions
# -------------------------------
def select_file():
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(
title="Select .docx or .xlsx file",
filetypes=[("Word and Excel files", "*.docx *.xlsx"), ("All files", "*.*")]
)
return file_path
def parse_datetime(prompt):
while True:
dt_str = input(prompt).strip()
try:
return datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")
except ValueError:
print("Invalid format. Use: YYYY-MM-DD HH:MM:SS (e.g., 2025-04-01 14:30:00)")
def change_docx_metadata(file_path, created_dt, modified_dt):
doc = Document(file_path)
# FIXED: Use 'core_properties' (with underscore)
props = doc.core_properties
# Set modified (always available)
props.modified = modified_dt
# Set created (fallback if not directly settable)
if hasattr(props, 'created'):
props.created = created_dt
else:
# Fallback: Manually update the XML in the docx zip
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
cp = props._element
created_el = OxmlElement(qn('dc:created'))
created_el.set(qn('xsi:type'), 'dcterms:W3CDTF')
created_el.text = created_dt.isoformat()
cp.insert(0, created_el) # Insert at beginning
doc.save(file_path)
def change_xlsx_metadata(file_path, created_dt, modified_dt):
wb = load_workbook(file_path)
# Ensure properties object exists
if not hasattr(wb, 'properties') or wb.properties is None:
wb.properties = WorkbookProperties()
wb.properties.created = created_dt
wb.properties.modified = modified_dt
wb.save(file_path)
def change_filesystem_timestamps(file_path, created_dt, modified_dt):
modified_ts = modified_dt.timestamp()
# Always set modified time
try:
os.utime(file_path, (modified_ts, modified_ts))
print(f"File system 'Modified' time set to: {modified_dt.strftime('%Y-%m-%d %H:%M:%S')}")
except Exception as e:
print(f"Failed to set modified time: {e}")
# Try to set creation time (macOS/Linux only)
if created_dt != modified_dt:
success = set_file_creation_time(file_path, created_dt)
if success:
print(f"File system 'Created' time set to: {created_dt.strftime('%Y-%m-%d %H:%M:%S')}")
else:
print("Created and Modified times are the same — skipping creation time change.")
# -------------------------------
# Main
# -------------------------------
def main():
print("Select a .docx or .xlsx file...")
file_path = select_file()
if not file_path:
print("No file selected.")
return
ext = os.path.splitext(file_path)[1].lower()
if ext not in ['.docx', '.xlsx']:
print("Error: Please select a .docx or .xlsx file.")
return
print("\nEnter timestamps in format: YYYY-MM-DD HH:MM:SS")
created_dt = parse_datetime("Enter CREATED date & time: ")
modified_dt = parse_datetime("Enter MODIFIED date & time: ")
print(f"\nApplying changes to: {os.path.basename(file_path)}")
print(f" Created → {created_dt}")
print(f" Modified → {modified_dt}")
# 1. Update internal metadata
try:
if ext == '.docx':
change_docx_metadata(file_path, created_dt, modified_dt)
print("Internal .docx metadata updated (Created & Modified).")
elif ext == '.xlsx':
change_xlsx_metadata(file_path, created_dt, modified_dt)
print("Internal .xlsx metadata updated (Created & Modified).")
except Exception as e:
print(f"Failed to update internal metadata: {e}")
return
# 2. Update file system timestamps
change_filesystem_timestamps(file_path, created_dt, modified_dt)
print("\nAll changes completed successfully!")
if __name__ == "__main__":
main()