夏令时变更后应用程序日期时间未同步问题咨询
夏令时变更后应用程序日期时间未同步问题咨询
我做了个用来测试夏令时变更的Windows窗体应用,操作流程是这样的:通过系统里的「自动调整夏令时」按钮切换夏令时开关,系统时间会跟着变,托盘里的时钟能看到时间差了1小时,但我的应用却一直显示旧时间,而且判断夏令时的isDaylightSaving变量值也没变化。只有重启应用之后,才能获取到正确的时间和夏令时状态。
我的应用核心代码片段如下:
public partial class Form1 : Form { private Label lblDateTime; private System.Windows.Forms.Timer timer; private TimeZoneInfo localTimeZone; public Form1() { InitializeComponent(); // Initialize the form and label this.Text = "Day Time Information"; this.Width = 400; this.Height = 200; lblDateTime = new Label(); // 这里省略了部分初始化代码... } }
现在我想请教下,怎么让应用在夏令时变更后,不用重启就能自动同步正确的时间和夏令时状态呢?
解决思路和方案
兄弟,这个问题我之前也碰到过,核心原因就是你缓存了时区信息,而且没监听系统的时间变更通知。给你几个实用的解决办法:
别缓存
TimeZoneInfo,每次更新都重新拿
你应该是在窗体初始化时就把localTimeZone赋值好了,但系统夏令时一变,这个缓存的实例不会自动跟着更新。所以每次要查时间或夏令时状态时,直接用TimeZoneInfo.Local获取最新的本地时区数据,别用初始化时存的那个值。监听系统的时间变更事件
Windows系统在改时间或夏令时的时候,会发一个WM_TIMECHANGE的消息,你可以在窗体里重写WndProc方法监听这个消息,一收到就触发更新:private const int WM_TIMECHANGE = 0x001E; protected override void WndProc(ref Message m) { if (m.Msg == WM_TIMECHANGE) { // 时间/夏令时变了,马上更新显示和状态 UpdateDateTimeDisplay(); } base.WndProc(ref m); }这里的
UpdateDateTimeDisplay就是你用来刷新标签显示的方法,里面要重新拿最新的时间和时区信息。优化定时器的刷新逻辑
如果你的定时器是用来定时刷时间的,那每次Tick触发时,都要重新获取当前时间和最新的时区状态,别用之前存的数据。比如:private void timer_Tick(object sender, EventArgs e) { DateTime now = DateTime.Now; // 每次都拿最新的时区 TimeZoneInfo currentZone = TimeZoneInfo.Local; bool isDaylight = currentZone.IsDaylightSavingTime(now); lblDateTime.Text = $"当前时间: {now:yyyy-MM-dd HH:mm:ss}\n夏令时状态: {isDaylight}"; }
小提醒
- 绝对不要初始化一次
TimeZoneInfo就一直用,系统时区(包括夏令时规则)变了之后,这个旧实例就失效了。 - 监听系统消息的方式是最及时的,比单纯靠定时器轮询要高效,能第一时间响应变更。
备注:内容来源于stack exchange,提问作者vico




