You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

夏令时变更后应用程序日期时间未同步问题咨询

夏令时变更后应用程序日期时间未同步问题咨询

我做了个用来测试夏令时变更的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

火山引擎 最新活动