C#双时区时钟设计

这是一个可直接运行的 C# WinForms 数字时钟程序,主界面同时显示北京和洛杉矶时间,采用24小时制且不显示秒。

cs 复制代码
using System;
using System.Drawing;
using System.Windows.Forms;

namespace DualDigitalClock
{
    public class ClockForm : Form
    {
        // 两个城市的时区
        private readonly TimeZoneInfo _beijingTz;
        private readonly TimeZoneInfo _losAngelesTz;

        // 显示控件
        private Label _beijingTime, _beijingDate;
        private Label _losAngelesTime, _losAngelesDate;

        private readonly Timer _timer;

        // 中文星期,避免依赖系统区域设置
        private static readonly string[] WeekNames =
            { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

        public ClockForm()
        {
            _beijingTz    = ResolveTimeZone("Asia/Shanghai",       "China Standard Time");
            _losAngelesTz = ResolveTimeZone("America/Los_Angeles", "Pacific Standard Time");

            // ---------- 窗体外观 ----------
            Text = "双时区数字时钟";
            StartPosition = FormStartPosition.CenterScreen;
            AutoScaleMode = AutoScaleMode.Dpi;
            FormBorderStyle = FormBorderStyle.FixedSingle;
            MaximizeBox = false;
            ClientSize = new Size(480, 300);
            BackColor = Color.FromArgb(28, 28, 32);
            ForeColor = Color.White;
            Font = new Font("Microsoft YaHei UI", 9f);

            // ---------- 布局 ----------
            var main = new TableLayoutPanel
            {
                Dock = DockStyle.Fill,
                ColumnCount = 1,
                RowCount = 2,
                Padding = new Padding(18, 14, 18, 14),
                BackColor = Color.Transparent
            };
            main.RowStyles.Add(new RowStyle(SizeType.Percent, 50f));
            main.RowStyles.Add(new RowStyle(SizeType.Percent, 50f));

            main.Controls.Add(CreateCityPanel("北京", out _beijingTime, out _beijingDate), 0, 0);
            main.Controls.Add(CreateCityPanel("洛杉矶", out _losAngelesTime, out _losAngelesDate), 0, 1);
            Controls.Add(main);

            // ---------- 定时刷新 ----------
            // 200ms 刷新一次,保证分钟切换足够及时(不显示秒,所以无需每秒刷新)
            _timer = new Timer { Interval = 200 };
            _timer.Tick += (s, e) => UpdateClocks();
            _timer.Start();

            UpdateClocks();
        }

        /// <summary>构建一个城市显示区块</summary>
        private Panel CreateCityPanel(string cityName, out Label timeLabel, out Label dateLabel)
        {
            var panel = new Panel { Dock = DockStyle.Fill, Margin = new Padding(0) };

            var city = new Label
            {
                Text = cityName,
                AutoSize = true,
                Font = new Font("Microsoft YaHei UI", 11f, FontStyle.Bold),
                ForeColor = Color.FromArgb(140, 195, 255),
                Location = new Point(0, 0)
            };

            timeLabel = new Label
            {
                Text = "--:--",
                AutoSize = false,
                Font = new Font("Consolas", 42f, FontStyle.Bold),
                ForeColor = Color.White,
                Location = new Point(-4, 22),
                Size = new Size(420, 64),
                TextAlign = ContentAlignment.MiddleLeft
            };

            dateLabel = new Label
            {
                Text = "",
                AutoSize = true,
                Font = new Font("Microsoft YaHei UI", 9.5f),
                ForeColor = Color.FromArgb(165, 165, 170),
                Location = new Point(2, 90)
            };

            panel.Controls.Add(city);
            panel.Controls.Add(timeLabel);
            panel.Controls.Add(dateLabel);
            return panel;
        }

        /// <summary>刷新两个城市的时间显示</summary>
        private void UpdateClocks()
        {
            DateTime utcNow = DateTime.UtcNow;

            DateTime beijing = TimeZoneInfo.ConvertTimeFromUtc(utcNow, _beijingTz);
            DateTime la      = TimeZoneInfo.ConvertTimeFromUtc(utcNow, _losAngelesTz);

            // 24 小时制,不显示秒 -> "HH:mm"
            _beijingTime.Text = beijing.ToString("HH:mm");
            _beijingDate.Text = FormatDate(beijing);

            _losAngelesTime.Text = la.ToString("HH:mm");
            _losAngelesDate.Text = FormatDate(la) + "   " + GetPacificAbbreviation(utcNow);
        }

        private static string FormatDate(DateTime dt)
        {
            return dt.ToString("yyyy-MM-dd") + "  " + WeekNames[(int)dt.DayOfWeek];
        }

        /// <summary>洛杉矶使用夏令时则返回 PDT,否则 PST</summary>
        private static string GetPacificAbbreviation(DateTime utcNow)
        {
            // 用 UTC 时间查询偏移量,避免 DateTimeKind 带来的歧义
            TimeZoneInfo tz = ResolveTimeZone("America/Los_Angeles", "Pacific Standard Time");
            TimeSpan offset = tz.GetUtcOffset(utcNow);
            return offset == tz.BaseUtcOffset ? "PST (UTC-8)" : "PDT (UTC-7)";
        }

        /// <summary>跨平台/跨框架解析时区:.NET 6+ 支持 IANA ID,旧版 Windows 需要 Windows ID</summary>
        private static TimeZoneInfo ResolveTimeZone(string ianaId, string windowsId)
        {
            foreach (string id in new[] { ianaId, windowsId })
            {
                try
                {
                    return TimeZoneInfo.FindSystemTimeZoneById(id);
                }
                catch (TimeZoneNotFoundException) { }
                catch (InvalidTimeZoneException) { }
            }
            throw new TimeZoneNotFoundException("找不到时区:" + ianaId + " / " + windowsId);
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            _timer.Stop();
            _timer.Dispose();
            base.OnFormClosed(e);
        }

        [STAThread]
        private static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new ClockForm());
        }
    }
}
相关推荐
sbjdhjd1 小时前
从污点追踪断点到 PHP-FPM 请求队列:HIDS PHP WebShell 样本复盘
开发语言·网络安全·数据挖掘·渗透测试·开源·php·shell
CSharp精选营1 小时前
.NET 接口从 800ms 干到 60ms:生产环境这几个优化点最关键
性能优化·c#·.net·efcore
SEO_juper2 小时前
Go 站点地图生成器:从首页爬全站,一键生成 sitemap.xml
xml·开发语言·人工智能·golang·node.js·seo·外贸独立站
懂点Tech9 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang10 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
美狐美颜SDK开放平台11 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq042411 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘5611 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
码匠许师傅11 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt