用 Tkinter 实现一个简单的干支纪年计算器

背景

TkDocs tutorial 里介绍了 Tkinter\text{Tkinter} Tkinter,其中有 A First (Real) Example 一文,这篇文章里有一个使用 Tkinter\text{Tkinter} Tkinter 生成图形化界面的简单例子。我想在那篇文章的基础上实战一下,于是想到可以写一个公元年份 ➡️ 干支纪年(其实严格来讲,一个公元年份并不能和一个干支纪年完全对应)的简易计算器。

正文

如何将公元年份转化为干支纪年

天干有如下 1010 10 个

  • 甲
  • 乙
  • 丙
  • 丁
  • 戊
  • 己
  • 庚
  • 辛
  • 壬
  • 癸

地支有如下 1212 12 个

  • 子
  • 丑
  • 寅
  • 卯
  • 辰
  • 巳
  • 午
  • 未
  • 申
  • 酉
  • 戌
  • 亥

计算对应的天干

公元 19841984 1984 年是甲子年。由于天干的数量是 1010 10,所以可以这样计算天干 ⬇️

python 复制代码
def calculate_tian_gan(specified_year):
    tian_gan_candidates = "甲乙丙丁戊己庚辛壬癸"
    candidates_cnt = len(tian_gan_candidates)
    last_digit = specified_year % candidates_cnt
    return tian_gan_candidates[(last_digit + 6) % candidates_cnt]

计算对应的地支

天干的数量( 1010 10)和地支的数量( 1212 12)都是( 6060 60)的约数,所以对公元年份 yy y 和 y+60y + 60 y+60 而言(假设 y>0y\gt0 y>0),它们对应的干支纪年是一样的。

公元 19841984 1984 年是甲子年,那么公元 184184 184 年也是甲子年( 1984−60×30=1841984-60\times 30=184 1984−60×30=184),那么公元 44 4 年也是甲子年( 184−60×3=4184-60\times 3=4 184−60×3=4),所以可以这样计算地支 ⬇️

python 复制代码
def calculate_di_zhi(specified_year):
    di_zhi_candidates = "子丑寅卯辰巳午未申酉戌亥"
    candidates_cnt = len(di_zhi_candidates)
    remaider = specified_year % candidates_cnt
    return di_zhi_candidates[(remaider + 8) % candidates_cnt]

完整的代码

A First (Real) Example 一文中有使用 Tkinter\text{Tkinter} Tkinter 生成图形化界面的简单例子。在它的基础上,可以写出以下 Python3\text{Python3} Python3 代码

python 复制代码
from tkinter import *
from tkinter import ttk

def calculate():
    try:
        specified_year = year.get()
        if (specified_year <= 0):
            result.set("请输入大于0的公元年份!")
            return
        tian_gan = calculate_tian_gan(specified_year)
        di_zhi = calculate_di_zhi(specified_year)
        result.set(tian_gan + di_zhi)
    except ValueError:
        pass

def calculate_tian_gan(specified_year):
    tian_gan_candidates = "甲乙丙丁戊己庚辛壬癸"
    candidates_cnt = len(tian_gan_candidates)
    last_digit = specified_year % candidates_cnt
    return tian_gan_candidates[(last_digit + 6) % candidates_cnt]

def calculate_di_zhi(specified_year):
    di_zhi_candidates = "子丑寅卯辰巳午未申酉戌亥"
    candidates_cnt = len(di_zhi_candidates)
    remaider = specified_year % candidates_cnt
    return di_zhi_candidates[(remaider + 8) % candidates_cnt]

root = Tk()
root.title("公元年份对应干支纪年计算器")

mainframe = ttk.Frame(root, padding=(3, 3, 12, 12))
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

year = IntVar()
year_entry = ttk.Entry(mainframe, width=7, textvariable=year)
year_entry.grid(column=2, row=1, sticky=(W, E))

ttk.Button(mainframe, text="对应的干支纪年:", command=calculate).grid(column=1, row=2, sticky=W)

ttk.Label(mainframe, text="公元年份:").grid(column=1, row=1, sticky=W)

result = StringVar()
ttk.Label(mainframe, textvariable=result).grid(column=2, row=2, sticky=(W, E))

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
mainframe.columnconfigure(2, weight=1)
for child in mainframe.winfo_children(): 
    child.grid_configure(padx=5, pady=5)

year_entry.focus()
root.bind("<Return>", calculate)

root.mainloop()

运行

请将上一小节展示的完整代码保存为 ganzhi.py。使用如下命令可以运行 ganzhi.py

bash 复制代码
python3 ganzhi.py

运行效果如下

我们输入一个正数,例如当前年份 20262026 2026,效果如下

再用其他年份验证一下(例如 19841984 1984 年)

运行结果符合预期

参考资料

相关推荐
hhzz7 小时前
【YOLO 入门到精通 04】理解任务与模型家族:7 大 CV 任务与 YOLO26 选型指南
人工智能·python·深度学习·yolo·计算机视觉
Escalating_xu7 小时前
【Python】使用库:标准库、第三方库、pip、项目实战与程序打包
java·python·pip
水獭比特7 小时前
Agent 工具审批不止一个按钮:用 v0.22.1 复盘入口、恢复和副作用
人工智能·python
谁在黄金彼岸7 小时前
nginx服务化五套方案原理解剖与选型
后端
谁在黄金彼岸7 小时前
WinSW在Win7上失败真相-实测与修复
后端
苦瓜打怪兽8 小时前
leetcode 热题100(11. 盛最多水的容器)
python·算法·leetcode
花间相见8 小时前
【后端开发|Redis进阶01】—— Redis分布式锁全解:从SETNX到Redisson看门狗,再到RedLock
后端·面试
llqbzllll8 小时前
A2A 1.0 到底和 MCP 差在哪:从 Agent Card、Task 到 Java 最小互操作
后端
花间相见8 小时前
【后端开发|JVM基础01】—— Java垃圾回收全解:从分代内存模型到各收集器的分代职责
后端
geovindu8 小时前
rust: Abstract Factory pattern
开发语言·后端·设计模式·rust·抽象工厂模式