From b786ea85d34fc3ba34cc2ccf4c11b6e571329ea9 Mon Sep 17 00:00:00 2001 From: Zichao Lin Date: Sun, 16 Jun 2024 16:50:01 +0800 Subject: [PATCH] first commit --- .gitignore | 1 + icon.ico | Bin 0 -> 67758 bytes icon.png | Bin 0 -> 5915 bytes main.py | 268 +++++++++++++++++++++++++++++++++++++++++++++++ ntp_config.json | 92 ++++++++++++++++ requirements.txt | 2 + 6 files changed, 363 insertions(+) create mode 100644 .gitignore create mode 100644 icon.ico create mode 100644 icon.png create mode 100644 main.py create mode 100644 ntp_config.json create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1960e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +output/ \ No newline at end of file diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..aaf167c22c212c9ff2a48eb343d541f60ed9f642 GIT binary patch literal 67758 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 literal 0 HcmV?d00001 diff --git a/main.py b/main.py new file mode 100644 index 0000000..15a6535 --- /dev/null +++ b/main.py @@ -0,0 +1,268 @@ +import json +import os +import ntplib +import time +import logging +from datetime import datetime +import win32api + +# 配置日志 +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +# ASCII 图像和软件信息 +ascii_art = r""" + _ ____________ + / | / /_ __/ __ \ _______ ______ ________ _____ + / |/ / / / / /_/ / / ___/ / / / __ \/ ___/ _ \/ ___/ + / /| / / / / ____/ (__ ) /_/ / / / / /__/ __/ / +/_/ |_/ /_/ /_/ /____/\__, /_/ /_/\___/\___/_/ + /____/ +""" + +software_info = """ +NTP syncer v1.0 +Version Date: 2024-06-16 +Copyright © 2024 earthjasonlin +Homepage: https://git.loliquq.cn/earthjasonlin/NTP-syncer +Description: This tool synchronizes your system time with multiple NTP servers, considering network delay and time correction. + +======================================== +""" + +# 打印 ASCII 图像和软件信息 +print(ascii_art) +print(software_info) + +# 定义 NTP 服务器池 +# ntp_servers = [ +# # 国家授时中心 NTP 服务器 +# "ntp.ntsc.ac.cn", "114.118.7.161", "114.118.7.163", +# # 中国 NTP 快速授时服务 +# "cn.ntp.org.cn", "223.113.97.98", "114.67.103.73", "119.29.26.206", "120.25.115.20", +# # 教育网 +# "edu.ntp.org.cn", "202.118.1.130", "202.118.1.81", "116.13.10.10", +# # 中国计量科学研究院 NIM 授时服务 +# "ntp1.nim.ac.cn", "ntp2.nim.ac.cn", "111.203.6.13", +# # 国际 NTP 快速授时服务 +# "cn.pool.ntp.org", "120.25.115.20", "111.230.189.174", "119.28.183.184", +# # 阿里云公共 NTP 服务器 +# "ntp.aliyun.com", "ntp1.aliyun.com", "ntp2.aliyun.com", "ntp3.aliyun.com", +# "ntp4.aliyun.com", "ntp5.aliyun.com", "ntp6.aliyun.com", "ntp7.aliyun.com", +# "203.107.6.88", "182.92.12.11", "120.25.108.11", +# # 腾讯云公共 NTP 服务器 +# "ntp.tencent.com", "ntp1.tencent.com", "ntp2.tencent.com", "ntp3.tencent.com", +# "ntp4.tencent.com", "ntp5.tencent.com", +# # 高通中国提供 NTP 服务 +# "time.izatcloud.net", "time.gpsonextra.net", +# # 教育网(高校自建) +# "ntp.sjtu.edu.cn", "ntp.neu.edu.cn", "ntp.bupt.edu.cn", "ntp.shu.edu.cn", +# # 国际 NTP 快速授时服务 +# "pool.ntp.org", "0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org", +# "asia.pool.ntp.org", "64.62.194.188", "81.169.199.94", +# # 谷歌公共 NTP 服务器 +# "time1.google.com", "time2.google.com", "time3.google.com", "time4.google.com", +# "216.239.35.0", "216.239.35.4", "216.239.35.8", "216.239.35.12", +# # 苹果公司公共 NTP 服务器 +# "time.apple.com", "time1.apple.com", "time2.apple.com", "time3.apple.com", +# "time4.apple.com", "time5.apple.com", "time6.apple.com", "time7.apple.com", +# "17.253.84.123", "17.253.84.125", "17.253.114.253", "17.253.116.253", +# # Cloudflare NTP 服务器 +# "time.cloudflare.com", "162.159.200.1", "162.159.200.123", +# # 微软 Windows NTP 服务器 +# "time.windows.com", "20.189.79.72", "52.148.114.188", "40.119.6.228", "51.137.137.111", +# # 美国标准技术研究院 NTP 服务器 +# "time.nist.gov", "time-nw.nist.gov", "time-a.nist.gov", "time-b.nist.gov", +# "128.138.141.172", "132.163.96.1", "132.163.96.2", "132.163.97.1", "132.163.97.2", +# ] + +# 默认配置 +default_config = { + "ntp_servers": [ + "ntp.ntsc.ac.cn", + "114.118.7.161", + "114.118.7.163", + "cn.ntp.org.cn", + "223.113.97.98", + "114.67.103.73", + "119.29.26.206", + "120.25.115.20", + "edu.ntp.org.cn", + "202.118.1.130", + "202.118.1.81", + "116.13.10.10", + "ntp1.nim.ac.cn", + "ntp2.nim.ac.cn", + "111.203.6.13", + "cn.pool.ntp.org", + "120.25.115.20", + "111.230.189.174", + "119.28.183.184", + "ntp.aliyun.com", + "ntp1.aliyun.com", + "ntp2.aliyun.com", + "ntp3.aliyun.com", + "ntp4.aliyun.com", + "ntp5.aliyun.com", + "ntp6.aliyun.com", + "ntp7.aliyun.com", + "203.107.6.88", + "182.92.12.11", + "120.25.108.11", + "ntp.tencent.com", + "ntp1.tencent.com", + "ntp2.tencent.com", + "ntp3.tencent.com", + "ntp4.tencent.com", + "ntp5.tencent.com", + "time.izatcloud.net", + "time.gpsonextra.net", + "ntp.sjtu.edu.cn", + "ntp.neu.edu.cn", + "ntp.bupt.edu.cn", + "ntp.shu.edu.cn", + "pool.ntp.org", + "0.pool.ntp.org", + "1.pool.ntp.org", + "2.pool.ntp.org", + "3.pool.ntp.org", + "asia.pool.ntp.org", + "64.62.194.188", + "81.169.199.94", + "time1.google.com", + "time2.google.com", + "time3.google.com", + "time4.google.com", + "216.239.35.0", + "216.239.35.4", + "216.239.35.8", + "216.239.35.12", + "time.apple.com", + "time1.apple.com", + "time2.apple.com", + "time3.apple.com", + "time4.apple.com", + "time5.apple.com", + "time6.apple.com", + "time7.apple.com", + "17.253.84.123", + "17.253.84.125", + "17.253.114.253", + "17.253.116.253", + "time.cloudflare.com", + "162.159.200.1", + "162.159.200.123", + "time.windows.com", + "20.189.79.72", + "52.148.114.188", + "40.119.6.228", + "51.137.137.111", + "time.nist.gov", + "time-nw.nist.gov", + "time-a.nist.gov", + "time-b.nist.gov", + "128.138.141.172", + "132.163.96.1", + "132.163.96.2", + "132.163.97.1", + "132.163.97.2", + ], + "update_interval": 600 +} + +# 从 JSON 文件中读取 NTP 服务器列表和更新间隔 +def load_config(file_path): + if not os.path.exists(file_path): + with open(file_path, 'w', encoding='utf-8') as file: + json.dump(default_config, file, ensure_ascii=False, indent=4) + logging.info(f"The configuration file {file_path} does not exist. A default configuration file has been created.") + logging.info("=" * 40) # 分隔符 + with open(file_path, 'r', encoding='utf-8') as file: + config = json.load(file) + return config['ntp_servers'], config['update_interval'] + +# 定义初始配置文件路径 +config_file_path = 'ntp_config.json' + +# 加载 NTP 服务器列表和更新间隔 +ntp_servers, update_interval = load_config(config_file_path) +last_successful_index = 0 + +def get_ntp_time(server): + client = ntplib.NTPClient() + + try: + send_time = time.time() + response = client.request(server, version=3) + receive_time = time.time() + + # 计算延迟 + delay = (receive_time - send_time) / 2 + + # 计算调整后的时间 + ntp_time = response.tx_time + delay + return ntp_time, delay, response.tx_time + except ntplib.NTPException as e: + logging.warning(f"Unable to get NTP time from {server}: {e}") + return None, None, None + +def update_system_time(ntp_time): + try: + # 获取当前系统时间(更新前) + current_system_time = datetime.utcnow() + + # 格式化 NTP 时间为 datetime 对象(使用 UTC 时间) + dt = datetime.utcfromtimestamp(ntp_time) + + # 获取星期几 (0 是星期一, 6 是星期日) + day_of_week = dt.weekday() + 1 # Windows API 需要 1 (星期一) 到 7 (星期日) + + # 调用 win32api 设置系统时间 + win32api.SetSystemTime( + dt.year, # 年 + dt.month, # 月 + day_of_week, # 星期几 + dt.day, # 日 + dt.hour, # 时 + dt.minute, # 分 + dt.second, # 秒 + int(dt.microsecond / 1000) # 毫秒 + ) + + # 获取当前系统时间(更新后) + new_system_time = datetime.utcnow() + + # 计算时间偏移(更新后的系统时间与NTP时间的差异) + correction = (new_system_time - current_system_time).total_seconds() + + logging.info(f"System time updated to: {dt.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]} UTC") + logging.info(f"Time correction: {correction*1000:.3f} ms") + except Exception as e: + logging.error(f"Unable to update system time: {e}") + +def main(): + global last_successful_index + + while True: + for i in range(len(ntp_servers)): + index = (last_successful_index + i) % len(ntp_servers) + server = ntp_servers[index] + + ntp_time, delay, raw_ntp_time = get_ntp_time(server) + + if ntp_time: + last_successful_index = index + logging.info(f"Got NTP time from {server}: {datetime.utcfromtimestamp(raw_ntp_time).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]} UTC") + logging.info(f"Network delay: {delay*1000:.3f} ms") + + update_system_time(ntp_time) + break + else: + logging.warning("All NTP servers attempted but unable to get time. Waiting for next attempt...") + + # 每隔一段时间检查一次 + time.sleep(update_interval) + + logging.info("=" * 40) # 分隔符 + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ntp_config.json b/ntp_config.json new file mode 100644 index 0000000..4ed0571 --- /dev/null +++ b/ntp_config.json @@ -0,0 +1,92 @@ +{ + "ntp_servers": [ + "ntp.ntsc.ac.cn", + "114.118.7.161", + "114.118.7.163", + "cn.ntp.org.cn", + "223.113.97.98", + "114.67.103.73", + "119.29.26.206", + "120.25.115.20", + "edu.ntp.org.cn", + "202.118.1.130", + "202.118.1.81", + "116.13.10.10", + "ntp1.nim.ac.cn", + "ntp2.nim.ac.cn", + "111.203.6.13", + "cn.pool.ntp.org", + "120.25.115.20", + "111.230.189.174", + "119.28.183.184", + "ntp.aliyun.com", + "ntp1.aliyun.com", + "ntp2.aliyun.com", + "ntp3.aliyun.com", + "ntp4.aliyun.com", + "ntp5.aliyun.com", + "ntp6.aliyun.com", + "ntp7.aliyun.com", + "203.107.6.88", + "182.92.12.11", + "120.25.108.11", + "ntp.tencent.com", + "ntp1.tencent.com", + "ntp2.tencent.com", + "ntp3.tencent.com", + "ntp4.tencent.com", + "ntp5.tencent.com", + "time.izatcloud.net", + "time.gpsonextra.net", + "ntp.sjtu.edu.cn", + "ntp.neu.edu.cn", + "ntp.bupt.edu.cn", + "ntp.shu.edu.cn", + "pool.ntp.org", + "0.pool.ntp.org", + "1.pool.ntp.org", + "2.pool.ntp.org", + "3.pool.ntp.org", + "asia.pool.ntp.org", + "64.62.194.188", + "81.169.199.94", + "time1.google.com", + "time2.google.com", + "time3.google.com", + "time4.google.com", + "216.239.35.0", + "216.239.35.4", + "216.239.35.8", + "216.239.35.12", + "time.apple.com", + "time1.apple.com", + "time2.apple.com", + "time3.apple.com", + "time4.apple.com", + "time5.apple.com", + "time6.apple.com", + "time7.apple.com", + "17.253.84.123", + "17.253.84.125", + "17.253.114.253", + "17.253.116.253", + "time.cloudflare.com", + "162.159.200.1", + "162.159.200.123", + "time.windows.com", + "20.189.79.72", + "52.148.114.188", + "40.119.6.228", + "51.137.137.111", + "time.nist.gov", + "time-nw.nist.gov", + "time-a.nist.gov", + "time-b.nist.gov", + "128.138.141.172", + "132.163.96.1", + "132.163.96.2", + "132.163.97.1", + "132.163.97.2" + ], + "update_interval": 10 +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..eb2fd9c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +ntplib +pywin32 \ No newline at end of file