# TimeSync **Repository Path**: ishiningway/TimeSync ## Basic Information - **Project Name**: TimeSync - **Description**: Windows下时间同步小工具 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-02 - **Last Updated**: 2026-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TimeSync 时间同步小工具 一个 Windows 桌面小工具,用于**从外部时间服务器同步系统时间**,也支持**手动设定时间**, 并能查看与设置 Windows 自带时间服务(W32Time)的配置。 - 目标平台:**Windows 10 22H2 (19045) / Windows 11**,x64 - 交付形态:**单个 exe 文件**,目标机**免装 .NET 运行时** - 权限要求:**必须管理员运行**(原因见下) - 依赖:无第三方运行时依赖;不出网除了查询时间服务器 --- ## 快速开始 1. 把 `TimeSync.exe` 拷到任意目录(例如 `D:\Tools\TimeSync\`) 2. **双击运行**,在 UAC 提示中点「是」 3. 打开「同步」页 → 点「同步并预览」→ 查看偏差 → 点「应用到系统」→ 勾选确认 > 想先无风险体验?在「设置」页勾选**演练模式**并保存。之后所有"应用"操作都只演练不落地。 --- ## 为什么必须管理员运行 改系统时间需要令牌**持有**「更改系统时间」特权(`SeSystemtimePrivilege`)。 实测(`whoami /priv`):普通用户令牌里**根本没有**这个特权,因此无法通过任何编程手段临时获得—— 必须整进程提权。所以程序清单声明了 `requireAdministrator`,启动时必然弹 UAC; 若拒绝 UAC,程序不会启动。 三种权限状态下的能力差异: | 能力 | 未提权 | 已提权 | 演练模式(设置项或 `--dry-run`) | | --- | --- | --- | --- | | 查看当前时间、时区 | ✅ | ✅ | ✅ | | 查询时间服务器、预览偏差 | ✅ | ✅ | ✅ | | 查看 W32Time 状态与配置 | ✅ | ✅ | ✅ | | **修改系统时间** | ❌ 按钮禁用并说明原因 | ✅ 需勾选确认 | ⚠️ 只演练不落地 | | **修改时间服务配置 / 启停服务** | ❌ 按钮禁用 | ✅ 需勾选确认 | 同左 | **只读模式**:未提权时界面顶部会显示蓝色说明条,写入类按钮禁用并给出原因—— 不会出现"点了按钮才报错"的情况。 --- ## 四个页面 | 页面 | 用途 | | --- | --- | | **同步** | 勾选时间服务器 → 「同步并预览」测量偏差(显示 offset / 往返延迟 / stratum / 逐台结果)→ 「应用到系统」 | | **手动设时** | 直接指定日期时间(精确到毫秒)→ 预览变更 → 应用;提供「恢复为刚才的时间」 | | **系统服务** | 查看 W32Time 状态与配置;设置启动类型、服务器列表、轮询间隔;启停服务;立即校时 | | **设置** | 服务器列表编辑、危险阈值、刷新间隔、主题(浅色/深色)、演练模式 | ### 为什么"同步并预览"是独立的按钮 改系统时间是**不可撤销**的全局操作(会影响 TLS 证书校验、Kerberos 认证、计划任务、 文件时间戳、正在运行的数据库与构建工具)。因此本工具把"测量"与"应用"分成两步: **预览只读,绝不改时间**;看清偏差后再决定是否应用。 ### 什么时候会弹确认框 | 操作 | 确认 | | --- | --- | | 「应用到系统」,调整量 ≤5 分钟 | **不弹框,直接应用** | | 「应用到系统」,调整量 >5 分钟 | 弹一次确认,并说明会破坏 Kerberos/TLS | | 「手动设时」应用 | 同上(按调整量决定) | | 「恢复为刚才的时间」 | 弹一次确认 | | 「系统服务」页改配置 / 停服务 | 弹一次确认(会改动系统级配置) | | 演练模式下的任何操作 | 不弹框(本来就不写任何东西) | 安全网是"演练模式 + 未提权只读 + 操作日志 + 写入前自动备份",而不是靠反复弹框拦截。 --- ## 时间服务默认不会自动校时(重要) 实测本机(Windows 10、工作组)状态: | 项 | 值 | | --- | --- | | `W32Time` 启动类型 | **手动(按需)** | | 触发器 | **仅"已加入的域"** | | 服务状态 | 停止 | | `w32tm /query /status` | 失败,`0x80070426`(服务未启动) | 也就是说:**在非域电脑上,Windows 默认不会自动校时**。很多人以为系统会自动同步,其实没有。 本工具的「系统服务」页会明确指出这一点。 若希望系统自己长期校时,可在「系统服务」页把启动类型设为**自动**并启动服务。 --- ## 夏令时与手动设时的两个细节 1. **不存在的时间**:夏令时开始那天被跳过的一小时(如 02:30)会被拒绝并解释原因—— 该时刻在现实中从未出现。 2. **重复的时间**:夏令时结束那天出现两次的一小时(如 01:30)**必须由你选择**按夏令时还是 标准时解释。程序不会替你猜——静默猜错会造成"设 9 点却变成 8 点"的一小时偏差。 --- ## 错误码对照 界面上的失败提示都会给出可执行的下一步,而不是笼统的"失败"。常见项: | 错误码 | 含义 | 怎么办 | | --- | --- | --- | | `NotElevated` | 未以管理员运行 | 关闭后以管理员身份重新启动 | | `PrivilegeNotHeld` | 令牌不持有"更改系统时间"特权(Win32 1314) | 确认是管理员;检查 `secpol.msc → 用户权限分配` 是否被策略移除 | | `NetworkUnreachable` | 域名解析失败 / 网络不可达 | 检查网络与 DNS;改用内网时间服务器 | | `NoResponse` | 服务器无响应(**多半是出站 UDP 123 被封锁**) | 联系网络管理员放通出站 UDP 123,或提供内网 NTP 服务器 | | `Timeout` | 超时 | 增大超时时间或更换服务器 | | `InvalidResponse` | 响应不符合 NTP 协议 | 换服务器;可能被中间设备干扰 | | `SourceMismatch` | 响应来源与请求不一致(已丢弃) | 属安全防护,换服务器即可 | | `KissOfDeath` | 服务器拒绝服务(KoD: `RATE`/`DENY`/`RSTR`) | 按提示降低频率或更换服务器 | | `ServerNotSynced` | 服务器自身未同步 | 换服务器 | | `ClockSetFailed` | **设置失败**:系统拒绝了写入 | 看提示里的 Win32 错误码;点「复制诊断信息」 | | `ClockSetUnstable` | **时间已改动**,但落地误差偏大 | 时间已经变了,不要重复点。误差偏大通常是本机时钟走得不准(见下方「本机时钟走不准」)或写入后被外部机制纠正 | | `ServiceNotRunning` | W32Time 未启动(`0x80070426`) | 「系统服务」页点「启动服务」后重试 | | `ServiceNotInstalled` | 本机没有 W32Time 服务 | 极罕见(被精简的系统);用本工具的同步功能即可 | | `ServiceStartFailed` / `ServiceStopFailed` | 服务启停失败 | 检查是否有依赖服务、是否被策略锁定 | | `ConfigWriteFailed` | 时间服务配置写入失败 | 确认管理员权限;检查组策略是否锁定 W32Time | | `ConfigVerifyFailed` | 配置已写但回读校验不一致 | 界面会展示期望值与实际值对照;多半被组策略覆盖 | | `DomainJoinedReadOnly` | 本机已加入域 | 域内时间由域策略管理,建议联系域管理员 | | `ValueOutOfRange` | 输入超出允许范围 | 修正输入(年份限 2000–2099) | | `Unknown` | 未归类的异常(已记录日志) | 用「复制诊断信息」反馈 | --- ## 域环境说明(重要) **已加入 Active Directory 域的电脑上,本工具只做只读检测与警告。** 三个原因: 1. 域内时间由域层级(`Type=NT5DS`)管理,手工改时间会被域策略或 W32Time 立即纠正回来。 2. Kerberos 要求客户端与域控的时间偏差 **≤5 分钟**;超出会导致域认证失败, 直接影响文件共享与打印。 3. 域内机器改时间通常违反企业策略。 因此程序会检测域状态并在界面上提示;如确需在域内校时,请使用 `w32tm /resync` (让系统按其自身策略同步)或联系域管理员。 --- ## 本机时钟走不准时会发生什么 本工具只能"把时间对准",无法让时钟**保持**准确。如果本机时钟本身走得很快或很慢, 你会看到:每次同步都有不小的偏差、应用之后过一会儿又偏了。 实测一台 Hyper-V 虚拟机(未启用宿主时间同步): | 观测 | 数值 | | --- | --- | | 时钟速度 | 每 700 ms 实际推进 **703 ms**,即 **+4.3 ms/秒(0.43%)** | | 累积速度 | 约 **4 分钟偏差 1 秒**、约 **1 小时偏差 15 秒** | **判断方法**:连续点两次「同步并预览」,间隔几分钟。若偏差稳 定朝一个方向增长(且标准差很小),就是本机时钟的问题,不是网络或工具的问题。 **处置建议**(按优先级): 1. **虚拟机**:启用宿主时间同步。Hyper-V 上以管理员身份运行 `sc start vmictimesync` 并设为自动启动;其他虚拟化平台用对应的集成服务(VMware Tools 等)。 程序启动时若检测到虚拟机环境,会直接在界面上提示这一点。 2. **启用 Windows 时间服务**:在「系统服务」页把启动类型设为**自动**并启动服务, 让系统自己周期性校时(本工具仍可用于手动校准)。 3. **物理机**:检查主板 RTC 电池;若 RTC 明显失准,短时间内无法根治, 只能依赖周期性校时。 --- ## 数据与配置存放位置 | 内容 | 路径 | | --- | --- | | 配置文件 | `%LOCALAPPDATA%\TimeSync\config.json` | | 日志(按天滚动,保留 30 天) | `%LOCALAPPDATA%\TimeSync\logs\timesync-<日期>.log` | | 时间服务配置备份 | `%LOCALAPPDATA%\TimeSync\w32time-backups\` | 本工具**默认不写入注册表、不注册服务、不创建计划任务、不建快捷方式**。 唯一例外:你在「系统服务」页点「应用配置」时,会按你的选择修改 `HKLM\SYSTEM\CurrentControlSet\Services\W32Time` 下的对应值(**写入前自动备份原值**)。 --- ## 卸载 **绿色版无需安装,删除 exe 即卸载程序本体。** 如需彻底清理用户数据: ```powershell Remove-Item "$env:LOCALAPPDATA\TimeSync" -Recurse -Force ``` 若你曾用「系统服务」页改过时间服务配置,并希望恢复系统出厂值,可在该页点「恢复默认值」 (恢复为 `Type=NTP`、`NtpServer=time.windows.com,0x9`、`SpecialPollInterval=32768`、 启动类型「手动」),或从 `w32time-backups\` 里的备份对照恢复。 --- ## 命令行参数 | 参数 | 用途 | | --- | --- | | 无 | 正常启动图形界面 | | `--dry-run` | **强制演练模式**:所有改时间操作都不落地(界面上不可关闭) | | `--diag` | 采集诊断报告(运行环境、内存、资源占用)后退出 | | `--diag=ui:毫秒` | 创建界面、稳定指定毫秒后采样资源并退出 | | `--diag=soak:轮次[:间隔秒]` | 浸泡测试:连续多轮同步并记录资源趋势(写入 `timesync-soak.csv`) | | `--diag=leak:次数` | 界面刷新泄漏测试:快速驱动多次时间刷新(写入 `timesync-leak.csv`) | --- ## 已知限制 1. **需要出站 UDP 123**。企业网络若封锁该端口,同步功能不可用(本工具暂无 HTTPS 时间源回退)。 错误提示会明确指向这一点。 2. **精度受网络路径不对称影响**。时钟偏差的误差上限约为 `(去程延迟 − 回程延迟)/2`, 因此公网同步在几十毫秒内波动是正常的;同机/局域网可显著更好。 3. **写入侧受系统时钟节拍量化**(约 15.6 ms)。读取侧精度远高于此(实测 100 ns 量级), 但"设置时间"的落地残差会落在节拍量级——界面上会如实显示残差。 4. **不支持 IPv6、不提供 NTP 服务端**(不会让本机变成对时源)。 5. **Windows 10 已于 2025-10-14 结束支持**。程序仍可在其上运行(实测通过), 但该平台已无安全更新,建议使用 Windows 11。 --- ## 从源码构建 需要 .NET 8 SDK(`winget install Microsoft.DotNet.SDK.8`)。 ```powershell dotnet build # 构建 dotnet test # 运行 321 项测试 pwsh -File tools/release.ps1 # 一键发布(含测试、清单校验、自包含校验、打包与校验和) ``` 发布产物位于 `release/v<版本>/`,包含单文件 exe、`SHA256.txt` 与说明文档。 更多工程信息见 [docs/设计方案.md](docs/设计方案.md) 与 [docs/测试报告.md](docs/测试报告.md)。