在 Python 中修改 Linux 系统时间,核心思想是:Python 本身没有直接修改系统时间的权限,它必须通过调用系统命令(如 date 或 timedatectl)来实现。

直接使用 os.system() 或 subprocess 模块来执行这些命令是常见的方法。普通用户通常没有权限修改系统时间,需要使用 sudo 权限。
下面我将介绍几种方法,并重点讲解最推荐、最安全的现代方法。
⚠️ 重要前提:权限问题
在 Linux 系统中,修改系统时间是受严格控制的操作,你需要:
- 使用
sudo:你的 Python 脚本必须以 root 权限运行。 - 正确的用户:确保运行脚本的用户在
sudoers文件中,并且可以无需密码或使用密码来执行特定的命令(/bin/date)。
使用 subprocess 模块(推荐)
这是最现代、最灵活、最安全的方式。subprocess 模块是 Python 官方推荐的用于创建子进程的接口。

使用 timedatectl(适用于现代 systemd 系统,如 Ubuntu 16+, CentOS 7+)
timedatectl 是 systemd 的一部分,是控制时间和日期的推荐工具,它更结构化,能更好地处理硬件时钟和 NTP 同步。
示例代码:
import subprocess
import sys
def set_system_time(new_time_str):
"""
使用 timedatectl 设置系统时间。
new_time_str: 必须是 "YYYY-MM-DD HH:MM:SS" 格式的字符串。
"""
try:
# 构建命令
# 注意:需要 root 权限
command = ['sudo', 'timedatectl', 'set-time', new_time_str]
# 执行命令
print(f"Executing command: {' '.join(command)}")
process = subprocess.run(command, check=True, capture_output=True, text=True)
print("系统时间设置成功!")
print(process.stdout)
return True
except subprocess.CalledProcessError as e:
print(f"设置时间失败!错误码: {e.returncode}", file=sys.stderr)
print(f"错误信息: {e.stderr}", file=sys.stderr)
return False
except FileNotFoundError:
print("错误: 'timedatectl' 命令未找到,请确保您在使用 systemd 的系统上。", file=sys.stderr)
return False
# --- 使用示例 ---
if __name__ == "__main__":
# 设置一个新时间,2025-10-27 15:30:00
new_time = "2025-10-27 15:30:00"
if set_system_time(new_time):
print(f"当前系统时间已更新为: {new_time}")
else:
print("时间更新失败。")
如何运行:
# 必须使用 sudo 运行 Python 脚本 sudo python3 your_script_name.py
优点:

- 现代标准:
systemd生态系统的首选工具。 - 功能强大:除了设置时间,还可以设置时区、控制 NTP 等。
- 状态清晰:命令本身有明确的成功/失败返回值。
使用 date 命令(传统方法)
date 命令非常通用,几乎所有 Linux 发行版都支持,但直接使用 date 设置时间有时会被系统服务(如 ntp 或 chronyd)覆盖。
示例代码:
import subprocess
import sys
def set_system_time_with_date(new_time_str):
"""
使用 date 命令设置系统时间。
new_time_str: 必须是 "MMDDHHMMYYYY" 或 "YYYY-MM-DD HH:MM:SS" 格式。
注意:格式取决于系统的 date 命令版本。
"""
try:
# 构建命令
# 注意:需要 root 权限
# 格式1: "MMDDHHMMYYYY" ( 102715302025)
# 格式2: "YYYY-MM-DD HH:MM:SS" (更直观)
command = ['sudo', 'date', '-s', new_time_str]
# 执行命令
print(f"Executing command: {' '.join(command)}")
process = subprocess.run(command, check=True, capture_output=True, text=True)
print("系统时间设置成功!")
# date 命令通常没有标准输出,print(process.stdout) 可能是空的
return True
except subprocess.CalledProcessError as e:
print(f"设置时间失败!错误码: {e.returncode}", file=sys.stderr)
print(f"错误信息: {e.stderr}", file=sys.stderr)
return False
except FileNotFoundError:
print("错误: 'date' 命令未找到。", file=sys.stderr)
return False
# --- 使用示例 ---
if __name__ == "__main__":
# 使用更直观的格式
new_time = "2025-10-27 15:30:00"
if set_system_time_with_date(new_time):
print(f"当前系统时间已更新为: {new_time}")
else:
print("时间更新失败。")
如何运行:
# 必须使用 sudo 运行 Python 脚本 sudo python3 your_script_name.py
注意:
date -s的格式可能因系统而异。YYYY-MM-DD HH:MM:SS是最通用的。- 如果系统运行着 NTP 服务,它会立即将你设置的时间同步掉,你可能需要先停止 NTP 服务。
使用 os.system(不推荐,仅作了解)
这是较老的方法,功能简单,但不如 subprocess 安全和灵活。
import os
import sys
def set_time_with_os_system(new_time_str):
"""
使用 os.system 设置时间。
"""
command = f'sudo date -s "{new_time_str}"'
print(f"Executing command: {command}")
exit_code = os.system(command)
if exit_code == 0:
print("系统时间设置成功!")
return True
else:
print(f"设置时间失败!错误码: {exit_code}", file=sys.stderr)
return False
# --- 使用示例 ---
if __name__ == "__main__":
new_time = "2025-10-27 15:30:00"
if set_time_with_os_system(new_time):
print(f"当前系统时间已更新为: {new_time}")
else:
print("时间更新失败。")
为什么不推荐?
- 安全风险:
new_time_str变量来自不可信的输入,可能会导致命令注入攻击(如果输入是"; rm -rf /;")。 - 功能有限:难以处理命令的输出和错误。
- 已过时:
subprocess是其替代品,设计更完善。
完整的最佳实践示例
下面是一个结合了 timedatectl 并处理了 NTP 服务的完整脚本,这在生产环境中非常有用。
import subprocess
import sys
import time
def stop_ntp_service():
"""尝试停止 ntpd 或 chronyd 服务"""
services_to_stop = ['chronyd', 'ntpd']
for service in services_to_stop:
try:
print(f"尝试停止服务: {service}")
subprocess.run(['sudo', 'systemctl', 'stop', service], check=True, capture_output=True)
print(f"成功停止服务: {service}")
return True
except subprocess.CalledProcessError:
continue # 尝试下一个服务
print("警告: 未找到或无法停止 NTP 服务,时间同步可能会覆盖设置。")
return False
def set_system_time_safely(new_time_str):
"""
安全地设置系统时间:先停止 NTP,再设置时间。
"""
# 1. 停止 NTP 服务
stop_ntp_service()
# 2. 设置时间
try:
command = ['sudo', 'timedatectl', 'set-time', new_time_str]
print(f"Executing command: {' '.join(command)}")
subprocess.run(command, check=True, capture_output=True, text=True)
print("系统时间设置成功!")
return True
except subprocess.CalledProcessError as e:
print(f"设置时间失败!错误码: {e.returncode}", file=sys.stderr)
print(f"错误信息: {e.stderr}", file=sys.stderr)
return False
if __name__ == "__main__":
# 设置一个新时间
new_time = "2025-10-27 15:30:00"
print(f"准备将系统时间设置为: {new_time}")
if set_system_time_safely(new_time):
# 验证时间是否已更改
verify_cmd = ['timedatectl', 'status']
result = subprocess.run(verify_cmd, capture_output=True, text=True)
print("\n--- 验证当前系统时间状态 ---")
print(result.stdout)
else:
print("时间更新失败。")
| 方法 | 命令 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
subprocess + timedatectl |
sudo timedatectl set-time ... |
现代、安全、功能强大、推荐 | 需要了解 systemd |
⭐⭐⭐⭐⭐ |
subprocess + date |
sudo date -s ... |
通用、简单 | 可能被 NTP 覆盖,格式依赖 | ⭐⭐⭐ |
os.system + date |
sudo date -s ... |
代码最简单 | 安全风险高,功能弱 | ⭐ (不推荐) |
最终建议:
- 优先使用
subprocess模块,因为它比os.system更安全、更强大。 - 优先使用
timedatectl命令,尤其是在现代 Linux 发行版上,它是管理时间的标准方式。 - 始终记得使用
sudo来运行你的 Python 脚本。 - 如果你的系统时间由 NTP 管理,在修改时间前先停止 NTP 服务,以防止你的设置被立即覆盖。
