如何写一个脚本自动校准时间

wen 实用脚本 2

本文目录导读:

如何写一个脚本自动校准时间

  1. Windows 批处理脚本(.bat)
  2. Windows PowerShell 脚本(.ps1)
  3. Linux Bash 脚本
  4. Python 跨平台脚本
  5. 使用方法:
  6. 设置自动执行:

Windows 批处理脚本(.bat)

@echo off
chcp 65001 >nul自动时间校准
echo 正在同步时间...
echo.
:: 方法1:使用Windows时间服务
w32tm /resync /force
if %errorlevel% equ 0 (
    echo 时间同步成功!
) else (
    echo 尝试使用其他服务器...
    w32tm /config /manualpeerlist:"time.windows.com,0x8 pool.ntp.org,0x8 time.nist.gov,0x8" /syncfromflags:MANUAL
    net stop w32time
    net start w32time
    w32tm /resync /force
)
echo.
echo 当前时间:%date% %time%
pause

Windows PowerShell 脚本(.ps1)

# 时间校准脚本
Write-Host "正在校准系统时间..." -ForegroundColor Cyan
# 获取当前时间
$oldTime = Get-Date
Write-Host "校准前时间: $oldTime" -ForegroundColor Yellow
# 尝试多种同步方式
try {
    # 方法1: Windows时间服务
    w32tm /resync /nowait /rediscover
    # 方法2: 设置NTP服务器
    $ntpServers = @(
        "pool.ntp.org",
        "time.windows.com",
        "time.nist.gov",
        "cn.ntp.org.cn"
    )
    foreach ($server in $ntpServers) {
        Write-Host "尝试连接: $server" -ForegroundColor Gray
        w32tm /config /manualpeerlist:$server /syncfromflags:MANUAL /reliable:YES /update
        w32tm /resync /nowait
    }
    # 显示新时间
    Start-Sleep -Seconds 2
    $newTime = Get-Date
    Write-Host "`n校准后时间: $newTime" -ForegroundColor Green
    Write-Host "时间差异: $(($newTime - $oldTime).TotalSeconds) 秒" -ForegroundColor Cyan
} catch {
    Write-Host "同步失败: $($_.Exception.Message)" -ForegroundColor Red
}
# 创建计划任务(每天运行)
$taskName = "AutoTimeSync"
$scriptPath = $MyInvocation.MyCommand.Path
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
try {
    Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal -Force
    Write-Host "`n计划任务创建成功!" -ForegroundColor Green
} catch {
    Write-Host "计划任务创建失败或无权限" -ForegroundColor Yellow
}
Read-Host "`n按回车键退出..."

Linux Bash 脚本

#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}开始校准系统时间...${NC}"
# 保存旧时间
old_time=$(date)
echo -e "校准前时间: ${YELLOW}$old_time${NC}"
# 检查是否有root权限
if [ "$EUID" -ne 0 ]; then 
    echo -e "${RED}请以root权限运行此脚本${NC}"
    echo "使用: sudo $0"
    exit 1
fi
# 检查并安装ntpdate
if ! command -v ntpdate &> /dev/null; then
    echo -e "${YELLOW}安装ntpdate...${NC}"
    apt-get update && apt-get install -y ntpdate
fi
# NTP服务器列表
NTP_SERVERS=(
    "pool.ntp.org"
    "time.windows.com"
    "time.nist.gov"
    "cn.pool.ntp.org"
    "ntp.aliyun.com"
    "ntp.tencent.com"
)
# 停止ntp服务(如果有)
systemctl stop ntp 2>/dev/null || true
systemctl stop ntpd 2>/dev/null || true
systemctl stop chronyd 2>/dev/null || true
# 尝试同步
echo -e "${YELLOW}正在同步时间...${NC}"
success=false
for server in "${NTP_SERVERS[@]}"; do
    echo -n "尝试 $server ... "
    if ntpdate -q $server &> /dev/null; then
        ntpdate -b $server
        if [ $? -eq 0 ]; then
            echo -e "${GREEN}成功${NC}"
            success=true
            break
        fi
    else
        echo -e "${RED}失败${NC}"
    fi
done
# 如果ntpdate失败,尝试使用chrony或systemd-timesyncd
if [ "$success" = false ]; then
    echo -e "${YELLOW}尝试使用chrony...${NC}"
    if command -v chronyd &> /dev/null; then
        systemctl restart chronyd
        sleep 2
        chronyc -a makestep 2>/dev/null
        success=$?
    else
        echo -e "${YELLOW}尝试使用systemd-timesyncd...${NC}"
        timedatectl set-ntp true
        systemctl restart systemd-timesyncd
        sleep 2
        timedatectl status
        success=true
    fi
fi
# 显示结果
new_time=$(date)
echo -e "\n校准后时间: ${GREEN}$new_time${NC}"
# 计算时间差
old_timestamp=$(date -d "$old_time" +%s 2>/dev/null)
new_timestamp=$(date -d "$new_time" +%s 2>/dev/null)
if [ ! -z "$old_timestamp" ] && [ ! -z "$new_timestamp" ]; then
    diff=$((new_timestamp - old_timestamp))
    echo -e "时间调整: ${YELLOW}$diff 秒${NC}"
fi
# 设置时区(如果需要)
# timedatectl set-timezone Asia/Shanghai
# 设置定时任务(每天凌晨执行)
cron_job="0 */6 * * * /usr/sbin/ntpdate pool.ntp.org > /dev/null 2>&1"
if ! crontab -l 2>/dev/null | grep -q "ntpdate"; then
    (crontab -l 2>/dev/null; echo "$cron_job") | crontab -
    echo -e "${GREEN}定时任务已添加(每6小时同步一次)${NC}"
fi
echo -e "${GREEN}时间校准完成!${NC}"

Python 跨平台脚本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import time
import socket
import struct
import platform
import subprocess
from datetime import datetime
def sync_time_windows():
    """Windows时间同步"""
    try:
        # 使用w32tm同步时间
        result = subprocess.run(
            ['w32tm', '/resync', '/force'],
            capture_output=True,
            text=True,
            timeout=10
        )
        return result.returncode == 0
    except Exception as e:
        print(f"Windows同步失败: {e}")
        return False
def sync_time_linux():
    """Linux时间同步"""
    try:
        # 尝试多种方法
        methods = [
            ['timedatectl', 'set-ntp', 'true'],
            ['systemctl', 'restart', 'systemd-timesyncd'],
            ['ntpdate', '-b', 'pool.ntp.org']
        ]
        for method in methods:
            try:
                subprocess.run(method, capture_output=True, timeout=5, check=True)
                return True
            except:
                continue
        return False
    except Exception as e:
        print(f"Linux同步失败: {e}")
        return False
def sync_time_ntp(server="pool.ntp.org"):
    """使用NTP协议直接同步"""
    try:
        # NTP请求包
        client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        client.settimeout(5)
        data = b'\x1b' + 47 * b'\0'
        client.sendto(data, (server, 123))
        data, address = client.recvfrom(1024)
        if data:
            # 解析NTP响应
            t = struct.unpack('!12I', data)[10]
            t -= 2208988800  # NTP时间到Unix时间
            ntp_time = datetime.fromtimestamp(t)
            # 设置系统时间
            if platform.system() == 'Windows':
                import win32api
                win32api.SetSystemTime(
                    ntp_time.year, ntp_time.month, ntp_time.weekday(),
                    ntp_time.day, ntp_time.hour, ntp_time.minute,
                    ntp_time.second, 0
                )
            else:
                # Linux需要root权限
                os.system(f'date -s "{ntp_time}"')
            return True
    except Exception as e:
        print(f"NTP同步失败: {e}")
        return False
def main():
    print("=" * 50)
    print(f"时间校准脚本 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 50)
    system = platform.system()
    print(f"系统类型: {system}")
    # 显示当前时间
    old_time = datetime.now()
    print(f"校准前时间: {old_time}")
    # 根据不同系统选择同步方法
    success = False
    if system == 'Windows':
        success = sync_time_windows()
    elif system == 'Linux':
        success = sync_time_linux()
        if not success:
            success = sync_time_ntp()
    else:
        print("不支持的平台")
        sys.exit(1)
    # 显示结果
    time.sleep(1)  # 等待时间同步完成
    new_time = datetime.now()
    if success:
        print(f"校准后时间: {new_time}")
        diff = (new_time - old_time).total_seconds()
        print(f"时间调整: {diff:.1f} 秒")
        print("✓ 时间校准成功!")
    else:
        print("✗ 时间校准失败!")
    print("=" * 50)
if __name__ == "__main__":
    # 检查管理员权限
    if platform.system() == 'Linux' and os.geteuid() != 0:
        print("请使用sudo运行此脚本")
        sys.exit(1)
    main()

使用方法:

Windows

  • 将批处理或PowerShell脚本保存为 .bat.ps1 文件
  • 以管理员身份运行
  • PowerShell需要执行策略:Set-ExecutionPolicy RemoteSigned

Linux

# 保存脚本
chmod +x calibrate_time.sh
sudo ./calibrate_time.sh

Python

pip install pywin32  # Windows需要
python calibrate_time.py

设置自动执行:

Windows - 任务计划程序

  1. 打开"任务计划程序"
  2. 创建基本任务
  3. 设置触发器(每天/每小时)
  4. 选择执行脚本

Linux - Crontab

# 每天6点执行
0 6 * * * /path/to/script.sh
# 每4小时执行
0 */4 * * * /path/to/script.sh

需要我详细解释某个部分的实现吗?

抱歉,评论功能暂时关闭!