当前位置:首页>python>一个基于 Python + Tkinter 的桌面时间工具时刻日期查看器

一个基于 Python + Tkinter 的桌面时间工具时刻日期查看器

  • 2026-10-11 06:48:45
一个基于 Python + Tkinter 的桌面时间工具时刻日期查看器

⏰ 时刻日期查看器

一个基于 Python + Tkinter 的桌面时间工具,集成实时时钟、月历、时间戳转换、倒计时、日期差计算和世界时钟,浅色主题设计,零外部依赖开箱即用。

📸 项目概述

  • 文件: datetime_viewer.py
  • 框架: Tkinter(Python 内置)
  • 主题: 浅色清新风格
  • 依赖: 无(农历为可选依赖)

🚀 快速开始

环境要求

  • Python 3.8+
  • 无需安装任何第三方库即可运行

运行

python datetime_viewer.py

可选:启用农历显示

pip install lunarcalendar

安装后程序自动在时钟区域显示农历日期。

📋 功能模块

1. ⏰ 实时时钟(顶部区域)

显示内容
示例
时间(大字体)
14:30:25
公历日期
2026年07月29日 星期三
农历日期
农历六月十五(需 lunarcalendar)
年度进度
第210天 | 第30周 | 距年末155天
当前时间戳
秒: 1785542425 | 毫秒: 1785542425000

每秒自动刷新,窗口置顶按钮可让工具常驻桌面。

2. 📅 月历面板(左侧)

功能
说明
当月日历
周一到周日网格布局
今天高亮
蓝色圆形背景标记
周末标红
周六日用玫红色显示
月份切换
◀ ▶ 按钮切换上下月
回到今天
「今天」按钮快速定位

3. ⏱ 时间戳工具(Tab 1)

功能
说明
实时时间戳
显示当前秒级 + 毫秒级时间戳
一键复制
复制当前时间戳到剪贴板
时间戳→日期
输入时间戳转为可读日期(支持秒/毫秒自动识别)
日期→时间戳
输入日期时间转为时间戳

输入格式:

  • 时间戳:1785542425(秒)或 1785542425000(毫秒)
  • 日期:2026-07-29 14:30:25

4. ⏳ 倒计时(Tab 2)

功能
说明
自定义倒计时
输入目标日期,显示剩余天/时/分
已过天数
如果目标日期已过,显示过去了多少天
下班倒计时
距今天 18:00 还有多久
周末倒计时
距本周六还有多久
元旦倒计时
距明年 1 月 1 日

输入格式:2026-12-31

5. 📅 日期差计算(Tab 3)

功能
说明
两日期相差
计算天数、周数、约几个月
快捷查询
30/90/180/365 天后是哪天

输入格式:2026-07-29

6. 🌍 世界时钟(底部)

同时显示 6 个城市的当前时间:

城市
时区
与北京时差
北京
UTC+8
本地
东京
UTC+9
+1h
伦敦
UTC+0
-8h
纽约
UTC-4
-12h
洛杉矶
UTC-7
-15h
悉尼
UTC+10
+2h

每秒自动更新。

🏗️ 界面布局

┌──────────────────────────────────────────────────┐│  14:30:25          2026年07月29日 星期三  📌置顶  ││                    农历 六月十五                   ││                    第210天 | 第30周 | 距年末155天   ││  秒: 1785542425 | 毫秒: 1785542425000            │├──────────────────────────────────────────────────┤│           │                                      ││  ◀ 2026年7月 ▶ [今天]│  [⏱时间戳] [⏳倒计时] [📅日期差]││                      │                           ││  一  二  三  四  五  六  日│  当前时间戳             ││  ..  ..   1   2   3   4   5│  1785542425  [复制]    ││   6   7   8   9  10  11  12│                       ││  13  14  15  16  17  18  19│  时间戳 → 日期          ││  20  21  22  23  24  25  26│  [输入框] [转换]        ││  27  28 [29] 30  31        │                       ││                      │  日期 → 时间戳              ││           │  [输入框] [转换]                       │├──────────────────────────────────────────────────┤│  🌍 世界时钟                                      ││  北京     东京     伦敦     纽约     洛杉矶   悉尼  ││  14:30   15:30   06:30   02:30   23:30   16:30   ││  本地    UTC+9   UTC+0   UTC-4   UTC-7   UTC+10  │└──────────────────────────────────────────────────┘

🎨 配色方案

采用清新浅色主题:

用途
颜色
色值
主背景
极浅灰蓝
#f8fafc
卡片背景
纯白
#ffffff
卡片边框
淡灰
#e2e8f0
主文字
深蓝黑
#1e293b
次要文字
灰蓝
#64748b
弱化文字
浅灰
#94a3b8
强调色
明亮蓝
#3b82f6
成功色
翠绿
#10b981
错误色
红色
#ef4444
周末/高亮
玫红
#e11d48
今天背景
蓝色
#3b82f6
按钮背景
极浅蓝
#eff6ff
输入框
浅灰
#f1f5f9

📦 依赖说明

依赖
必需
用途
tkinter
✅ 内置
GUI 界面
calendar
✅ 内置
月历生成
datetime
✅ 内置
日期时间处理
lunarcalendar
❌ 可选
农历日期显示

⚠️ 注意事项

时区说明

世界时钟使用固定 UTC 偏移量,未处理夏令时。实际使用中:

  • 伦敦夏令时为 UTC+1(3月~10月)
  • 纽约夏令时为 UTC-4(3月~11月)
  • 如需精确时区,可安装 pytz 扩展

农历显示

  • 未安装 lunarcalendar 时会显示提示文字,不影响其他功能
  • 安装命令:pip install lunarcalendar

时间戳识别

  • 输入 10 位数字 → 按秒级时间戳处理
  • 输入 13 位数字 → 按毫秒级时间戳处理(自动除以 1000)

🔧 自定义修改

修改世界时钟城市

self.world_zones = [    ("北京", 8), ("东京", 9), ("伦敦", 0),    ("纽约", -4), ("洛杉矶", -7), ("悉尼", 10),# 添加更多城市    ("柏林", 2), ("迪拜", 4), ("新加坡", 8),]

修改倒计时目标

在 _refresh_common_countdowns 方法中添加:

targets = [    ("今天下班 (18:00)", datetime(now.year, now.month, now.day, 18, 0, 0)),    ("本周末", now + timedelta(days=(5 - now.weekday()) % 7)),    ("元旦", datetime(now.year + 1, 1, 1)),# 添加自定义    ("春节", datetime(2027, 2, 6)),    ("国庆", datetime(now.year, 10, 1)),]

修改时钟字体大小

F_CLOCK = ("Segoe UI", 42, "bold")  # 改为你喜欢的大小

打包为 exe

pip install pyinstallerpyinstaller --onefile --windowed --name "DateTimeViewer" datetime_viewer.py

📄

# -*- coding: utf-8 -*-"""时刻日期查看器 - 浅色主题 GUI功能:实时时钟、月历、时间戳工具、倒计时、世界时钟、日期差计算依赖:tkinter(内置)可选:pip install lunarcalendar"""import tkinter as tkfrom tkinter import ttk, messageboximport calendarimport timefrom datetime import datetime, timedelta, timezone# ══════ 浅色主题配色 ══════BG = "#f8fafc"CARD = "#ffffff"BORDER = "#e2e8f0"TEXT = "#1e293b"TEXT_SEC = "#64748b"TEXT_WEAK = "#94a3b8"ACCENT = "#3b82f6"GREEN = "#10b981"YELLOW = "#f59e0b"RED = "#ef4444"PINK = "#e11d48"BTN_BG = "#eff6ff"BTN_FG = "#1d4ed8"INPUT_BG = "#f1f5f9"TODAY_BG = "#3b82f6"TODAY_FG = "#ffffff"SELECT_BG = "#dbeafe"F_CLOCK = ("Segoe UI", 42, "bold")F_DATE = ("Microsoft YaHei", 13)F_TITLE = ("Microsoft YaHei", 11, "bold")F_BODY = ("Microsoft YaHei", 10)F_SMALL = ("Microsoft YaHei", 9)F_MONO = ("Consolas", 11)F_CAL = ("Microsoft YaHei", 10)F_CAL_HEAD = ("Microsoft YaHei", 9, "bold")classDateTimeViewer:def__init__(self):        self.root = tk.Tk()        self.root.title("时刻日期查看器")        sw = self.root.winfo_screenwidth()        sh = self.root.winfo_screenheight()        w, h = min(sw - 80, 960), min(sh - 80, 680)        self.root.geometry(f"{w}x{h}+{(sw-w)//2}+{(sh-h)//2}")        self.root.configure(bg=BG)        self.root.resizable(True, True)        self.cal_year = datetime.now().year        self.cal_month = datetime.now().month        self.topmost = False        self._build_ui()        self._update_clock()def_card(self, parent, **kwargs):"""创建卡片容器"""        f = tk.Frame(parent, bg=CARD, bd=1, relief="solid",                     highlightbackground=BORDER, highlightthickness=1, **kwargs)return fdef_build_ui(self):# 顶部时钟区        self._build_clock()# 中部主区域        mid = tk.Frame(self.root, bg=BG)        mid.pack(fill="both", expand=True, padx=16, pady=(0, 8))# 左侧日历        self._build_calendar(mid)# 右侧工具区        self._build_tools(mid)# 底部世界时钟        self._build_world_clock()# ══════ 顶部时钟 ══════def_build_clock(self):        clock_card = self._card(self.root)        clock_card.pack(fill="x", padx=16, pady=(12, 8))        top_row = tk.Frame(clock_card, bg=CARD)        top_row.pack(fill="x", padx=16, pady=(12, 4))# 时钟大字        self.lbl_time = tk.Label(top_row, text="00:00:00", font=F_CLOCK,                                 bg=CARD, fg=TEXT)        self.lbl_time.pack(side="left")# 右侧信息        info_frame = tk.Frame(top_row, bg=CARD)        info_frame.pack(side="right", anchor="e")        self.lbl_date = tk.Label(info_frame, text="", font=F_DATE, bg=CARD, fg=TEXT)        self.lbl_date.pack(anchor="e")        self.lbl_lunar = tk.Label(info_frame, text="", font=F_BODY, bg=CARD, fg=TEXT_SEC)        self.lbl_lunar.pack(anchor="e")        self.lbl_year_info = tk.Label(info_frame, text="", font=F_SMALL, bg=CARD, fg=TEXT_WEAK)        self.lbl_year_info.pack(anchor="e")# 置顶按钮        self.pin_btn = tk.Button(top_row, text="📌 置顶", font=F_SMALL, bg=BTN_BG,                                 fg=BTN_FG, relief="flat", padx=8, command=self._toggle_topmost)        self.pin_btn.pack(side="right", padx=(0, 12))# ══════ 月历面板 ══════def_build_calendar(self, parent):        left = self._card(parent)        left.pack(side="left", fill="both", padx=(0, 6), pady=0, expand=False)# 月份导航        nav = tk.Frame(left, bg=CARD)        nav.pack(fill="x", padx=12, pady=(10, 4))        tk.Button(nav, text="◀", font=F_BODY, bg=BTN_BG, fg=BTN_FG, relief="flat",                  width=3, command=self._prev_month).pack(side="left")        self.lbl_month = tk.Label(nav, text="", font=F_TITLE, bg=CARD, fg=TEXT)        self.lbl_month.pack(side="left", expand=True)        tk.Button(nav, text="▶", font=F_BODY, bg=BTN_BG, fg=BTN_FG, relief="flat",                  width=3, command=self._next_month).pack(side="left")        tk.Button(nav, text="今天", font=F_SMALL, bg=ACCENT, fg="#ffffff", relief="flat",                  padx=8, command=self._goto_today).pack(side="left", padx=(8, 0))# 星期头        week_frame = tk.Frame(left, bg=CARD)        week_frame.pack(fill="x", padx=12, pady=(4, 0))        weekdays = ["一", "二", "三", "四", "五", "六", "日"]for i, d in enumerate(weekdays):            color = PINK if i >= 5else TEXT_SEC            tk.Label(week_frame, text=d, font=F_CAL_HEAD, bg=CARD, fg=color,                     width=4).grid(row=0, column=i, pady=2)# 日期格子        self.cal_frame = tk.Frame(left, bg=CARD)        self.cal_frame.pack(fill="both", expand=True, padx=12, pady=(0, 10))        self.cal_labels = []for r in range(6):            row = []for c in range(7):                lbl = tk.Label(self.cal_frame, text="", font=F_CAL, bg=CARD,                               fg=TEXT, width=4, height=1)                lbl.grid(row=r, column=c, pady=1, padx=1)                row.append(lbl)            self.cal_labels.append(row)        self._refresh_calendar()def_refresh_calendar(self):        self.lbl_month.configure(text=f"{self.cal_year}年 {self.cal_month}月")        today = datetime.now()        cal = calendar.Calendar(firstweekday=0)        days = cal.monthdayscalendar(self.cal_year, self.cal_month)for r in range(6):for c in range(7):                lbl = self.cal_labels[r][c]if r < len(days) and days[r][c] != 0:                    day = days[r][c]                    lbl.configure(text=str(day))# 今天高亮if (self.cal_year == today.year and self.cal_month == today.monthand day == today.day):                        lbl.configure(bg=TODAY_BG, fg=TODAY_FG)elif c >= 5:  # 周末                        lbl.configure(bg=CARD, fg=PINK)else:                        lbl.configure(bg=CARD, fg=TEXT)else:                    lbl.configure(text="", bg=CARD, fg=CARD)def_prev_month(self):        self.cal_month -= 1if self.cal_month < 1:            self.cal_month = 12            self.cal_year -= 1        self._refresh_calendar()def_next_month(self):        self.cal_month += 1if self.cal_month > 12:            self.cal_month = 1            self.cal_year += 1        self._refresh_calendar()def_goto_today(self):        now = datetime.now()        self.cal_year = now.year        self.cal_month = now.month        self._refresh_calendar()# ══════ 右侧工具区 ══════def_build_tools(self, parent):        right = tk.Frame(parent, bg=BG)        right.pack(side="right", fill="both", expand=True, padx=(6, 0))        notebook = ttk.Notebook(right)        notebook.pack(fill="both", expand=True)# 配置 ttk 样式        style = ttk.Style()        style.configure("TNotebook", background=BG)        style.configure("TNotebook.Tab", background=BTN_BG, foreground=TEXT,                        padding=[12, 4], font=F_BODY)        style.map("TNotebook.Tab", background=[("selected", CARD)],                  foreground=[("selected", ACCENT)])# Tab1: 时间戳工具        ts_frame = tk.Frame(notebook, bg=CARD)        notebook.add(ts_frame, text="  ⏱ 时间戳  ")        self._build_timestamp_tab(ts_frame)# Tab2: 倒计时        cd_frame = tk.Frame(notebook, bg=CARD)        notebook.add(cd_frame, text="  ⏳ 倒计时  ")        self._build_countdown_tab(cd_frame)# Tab3: 日期计算        dc_frame = tk.Frame(notebook, bg=CARD)        notebook.add(dc_frame, text="  📅 日期差  ")        self._build_date_calc_tab(dc_frame)def_build_timestamp_tab(self, parent):        px = 12        tk.Label(parent, text="当前时间戳", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        ts_row = tk.Frame(parent, bg=CARD)        ts_row.pack(fill="x", padx=px, pady=4)        self.lbl_ts = tk.Label(ts_row, text="", font=F_MONO, bg=INPUT_BG, fg=TEXT,                               padx=10, pady=4, relief="flat")        self.lbl_ts.pack(side="left", fill="x", expand=True)        tk.Button(ts_row, text="复制", font=F_SMALL, bg=BTN_BG, fg=BTN_FG,                  relief="flat", padx=8, command=self._copy_ts).pack(side="left", padx=(6, 0))# 时间戳转日期        tk.Label(parent, text="时间戳 → 日期", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        row1 = tk.Frame(parent, bg=CARD)        row1.pack(fill="x", padx=px, pady=4)        self.ts_input = tk.Entry(row1, font=F_MONO, bg=INPUT_BG, fg=TEXT, relief="flat", bd=1)        self.ts_input.pack(side="left", fill="x", expand=True, ipady=3)        self.ts_input.insert(0, str(int(time.time())))        tk.Button(row1, text="转换", font=F_SMALL, bg=ACCENT, fg="#ffffff",                  relief="flat", padx=10, command=self._ts_to_date).pack(side="left", padx=(6, 0))        self.lbl_ts_result = tk.Label(parent, text="", font=F_BODY, bg=CARD, fg=GREEN)        self.lbl_ts_result.pack(anchor="w", padx=px, pady=4)# 日期转时间戳        tk.Label(parent, text="日期 → 时间戳", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        row2 = tk.Frame(parent, bg=CARD)        row2.pack(fill="x", padx=px, pady=4)        self.date_input = tk.Entry(row2, font=F_MONO, bg=INPUT_BG, fg=TEXT, relief="flat", bd=1)        self.date_input.pack(side="left", fill="x", expand=True, ipady=3)        self.date_input.insert(0, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))        tk.Button(row2, text="转换", font=F_SMALL, bg=ACCENT, fg="#ffffff",                  relief="flat", padx=10, command=self._date_to_ts).pack(side="left", padx=(6, 0))        self.lbl_date_result = tk.Label(parent, text="", font=F_BODY, bg=CARD, fg=GREEN)        self.lbl_date_result.pack(anchor="w", padx=px, pady=4)def_build_countdown_tab(self, parent):        px = 12        tk.Label(parent, text="自定义倒计时", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        row = tk.Frame(parent, bg=CARD)        row.pack(fill="x", padx=px, pady=4)        tk.Label(row, text="目标日期:", font=F_BODY, bg=CARD, fg=TEXT).pack(side="left")        self.cd_input = tk.Entry(row, font=F_MONO, bg=INPUT_BG, fg=TEXT, relief="flat", bd=1, width=16)        self.cd_input.pack(side="left", padx=6, ipady=3)        self.cd_input.insert(0, f"{datetime.now().year}-12-31")        tk.Button(row, text="计算", font=F_SMALL, bg=ACCENT, fg="#ffffff",                  relief="flat", padx=10, command=self._calc_countdown).pack(side="left")        self.lbl_countdown = tk.Label(parent, text="", font=("Microsoft YaHei", 14, "bold"),                                      bg=CARD, fg=ACCENT)        self.lbl_countdown.pack(anchor="w", padx=px, pady=(8, 4))# 常用倒计时        tk.Label(parent, text="常用倒计时", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        self.countdown_list = tk.Frame(parent, bg=CARD)        self.countdown_list.pack(fill="x", padx=px, pady=4)        self._refresh_common_countdowns()def_build_date_calc_tab(self, parent):        px = 12        tk.Label(parent, text="日期差计算", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(12, 4))        row1 = tk.Frame(parent, bg=CARD)        row1.pack(fill="x", padx=px, pady=4)        tk.Label(row1, text="日期A:", font=F_BODY, bg=CARD, fg=TEXT).pack(side="left")        self.dateA_input = tk.Entry(row1, font=F_MONO, bg=INPUT_BG, fg=TEXT, relief="flat", bd=1, width=14)        self.dateA_input.pack(side="left", padx=6, ipady=3)        self.dateA_input.insert(0, datetime.now().strftime("%Y-%m-%d"))        row2 = tk.Frame(parent, bg=CARD)        row2.pack(fill="x", padx=px, pady=4)        tk.Label(row2, text="日期B:", font=F_BODY, bg=CARD, fg=TEXT).pack(side="left")        self.dateB_input = tk.Entry(row2, font=F_MONO, bg=INPUT_BG, fg=TEXT, relief="flat", bd=1, width=14)        self.dateB_input.pack(side="left", padx=6, ipady=3)        self.dateB_input.insert(0, (datetime.now() + timedelta(days=100)).strftime("%Y-%m-%d"))        tk.Button(parent, text="计算日期差", font=F_BODY, bg=ACCENT, fg="#ffffff",                  relief="flat", padx=16, command=self._calc_date_diff).pack(anchor="w", padx=px, pady=(8, 4))        self.lbl_diff = tk.Label(parent, text="", font=("Microsoft YaHei", 12, "bold"),                                 bg=CARD, fg=ACCENT)        self.lbl_diff.pack(anchor="w", padx=px, pady=4)# 快捷操作        tk.Label(parent, text="快捷查询", font=F_TITLE, bg=CARD, fg=TEXT).pack(anchor="w", padx=px, pady=(16, 4))        quick_frame = tk.Frame(parent, bg=CARD)        quick_frame.pack(fill="x", padx=px, pady=4)for text, days in [("30天后", 30), ("90天后", 90), ("180天后", 180), ("365天后", 365)]:            target = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")            tk.Label(quick_frame, text=f"{text}: {target}", font=F_SMALL,                     bg=INPUT_BG, fg=TEXT_SEC, padx=8, pady=3).pack(anchor="w", pady=2)# ══════ 底部世界时钟 ══════def_build_world_clock(self):        world_card = self._card(self.root)        world_card.pack(fill="x", padx=16, pady=(0, 12))        tk.Label(world_card, text="🌍 世界时钟", font=F_TITLE, bg=CARD, fg=TEXT).pack(            anchor="w", padx=12, pady=(8, 4))        self.world_frame = tk.Frame(world_card, bg=CARD)        self.world_frame.pack(fill="x", padx=12, pady=(0, 10))        self.world_zones = [            ("北京", 8), ("东京", 9), ("伦敦", 0),            ("纽约", -4), ("洛杉矶", -7), ("悉尼", 10),        ]        self.world_labels = []for i, (city, offset) in enumerate(self.world_zones):            cf = tk.Frame(self.world_frame, bg=INPUT_BG, padx=10, pady=6)            cf.pack(side="left", padx=4, pady=2, fill="x", expand=True)            tk.Label(cf, text=city, font=F_SMALL, bg=INPUT_BG, fg=TEXT_SEC).pack()            lbl = tk.Label(cf, text="--:--", font=F_MONO, bg=INPUT_BG, fg=TEXT)            lbl.pack()            diff = offset - 8# 与北京时差            diff_str = f"UTC{offset:+d}"if offset != 8else"本地"            tk.Label(cf, text=diff_str, font=("Microsoft YaHei", 8), bg=INPUT_BG, fg=TEXT_WEAK).pack()            self.world_labels.append((lbl, offset))# ══════ 时钟更新 ══════def_update_clock(self):        now = datetime.now()# 时间        self.lbl_time.configure(text=now.strftime("%H:%M:%S"))# 日期        weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]        self.lbl_date.configure(text=f"{now.strftime('%Y年%m月%d日')}{weekdays[now.weekday()]}")# 农历(尝试加载)        lunar_text = self._get_lunar(now)        self.lbl_lunar.configure(text=lunar_text)# 年度信息        day_of_year = now.timetuple().tm_yday        week_of_year = int(now.strftime("%W"))        days_left = (datetime(now.year, 12, 31) - now).days        self.lbl_year_info.configure(            text=f"第{day_of_year}天 | 第{week_of_year}周 | 距年末{days_left}天")# 时间戳        ts = int(now.timestamp())        ms_ts = int(now.timestamp() * 1000)        self.lbl_ts.configure(text=f"秒: {ts}  |  毫秒: {ms_ts}")# 世界时钟        utc_now = datetime.now(timezone.utc)for lbl, offset in self.world_labels:            tz_time = utc_now + timedelta(hours=offset)            lbl.configure(text=tz_time.strftime("%H:%M:%S"))        self.root.after(1000, self._update_clock)def_get_lunar(self, dt):"""获取农历日期"""try:from lunarcalendar import Converter, Solar            solar = Solar(dt.year, dt.month, dt.day)            lunar = Converter.Solar2Lunar(solar)            months = ["正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"]            days = ["初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十","十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十","廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"]            m = months[lunar.month - 1]            d = days[lunar.day - 1] if lunar.day <= 30else str(lunar.day)returnf"农历 {m}月{d}"except ImportError:return"(安装 lunarcalendar 可显示农历)"except Exception:return""# ══════ 工具方法 ══════def_copy_ts(self):        ts = str(int(time.time()))        self.root.clipboard_clear()        self.root.clipboard_append(ts)def_ts_to_date(self):try:            ts = int(self.ts_input.get().strip())if ts > 9999999999:  # 毫秒级                ts = ts // 1000            dt = datetime.fromtimestamp(ts)            self.lbl_ts_result.configure(text=f"→ {dt.strftime('%Y-%m-%d %H:%M:%S')}", fg=GREEN)except Exception as e:            self.lbl_ts_result.configure(text=f"错误: {e}", fg=RED)def_date_to_ts(self):try:            text = self.date_input.get().strip()            dt = datetime.strptime(text, "%Y-%m-%d %H:%M:%S")            ts = int(dt.timestamp())            self.lbl_date_result.configure(text=f"→ {ts} (秒)  |  {ts*1000} (毫秒)", fg=GREEN)except Exception as e:            self.lbl_date_result.configure(text=f"错误: {e}", fg=RED)def_calc_countdown(self):try:            text = self.cd_input.get().strip()            target = datetime.strptime(text, "%Y-%m-%d")            now = datetime.now()            delta = target - nowif delta.total_seconds() > 0:                days = delta.days                hours = delta.seconds // 3600                mins = (delta.seconds % 3600) // 60                self.lbl_countdown.configure(                    text=f"距 {text} 还有 {days}天 {hours}时 {mins}分", fg=ACCENT)else:                days = abs(delta.days)                self.lbl_countdown.configure(text=f"{text} 已过去 {days} 天", fg=RED)except Exception as e:            self.lbl_countdown.configure(text=f"格式错误(请用 YYYY-MM-DD)", fg=RED)def_refresh_common_countdowns(self):for w in self.countdown_list.winfo_children():            w.destroy()        now = datetime.now()        targets = [            ("今天下班 (18:00)", datetime(now.year, now.month, now.day, 18, 0, 0)),            ("本周末", now + timedelta(days=(5 - now.weekday()) % 7)),            ("元旦", datetime(now.year + 1, 1, 1)),        ]for name, target in targets:            delta = target - nowif delta.total_seconds() > 0:if delta.days > 0:                    text = f"{name}:{delta.days}天"else:                    h = delta.seconds // 3600                    m = (delta.seconds % 3600) // 60                    text = f"{name}:{h}时{m}分"                color = GREENelse:                text = f"{name}:已过"                color = TEXT_WEAK            tk.Label(self.countdown_list, text=text, font=F_BODY, bg=CARD, fg=color).pack(anchor="w", pady=1)def_calc_date_diff(self):try:            a = datetime.strptime(self.dateA_input.get().strip(), "%Y-%m-%d")            b = datetime.strptime(self.dateB_input.get().strip(), "%Y-%m-%d")            diff = abs((b - a).days)            weeks = diff // 7            months_approx = diff / 30.44            self.lbl_diff.configure(                text=f"相差 {diff} 天 (约 {weeks} 周 / {months_approx:.1f} 个月)", fg=ACCENT)except Exception:            self.lbl_diff.configure(text="格式错误(请用 YYYY-MM-DD)", fg=RED)def_toggle_topmost(self):        self.topmost = not self.topmost        self.root.attributes("-topmost", self.topmost)        self.pin_btn.configure(            text="📌 已置顶"if self.topmost else"📌 置顶",            bg=ACCENT if self.topmost else BTN_BG,            fg="#ffffff"if self.topmost else BTN_FG)defrun(self):        self.root.mainloop()if __name__ == "__main__":    app = DateTimeViewer()    app.run()

MIT License

最新文章

随机文章