这是一个可直接运行的 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());
}
}
}
