Tkinter实现干支纪年计算器
基于Tkinter框架开发公元年份转干支纪年的图形界面计算器,以1984年甲子年为基准,通过年份模10加6取天干、模12加8取地支实现快速转换,提供直观易用的实用小工具。
干支纪年计算器:基于Tkinter的实用工具
TkDocs tutorial 里有一篇《A First (Real) Example》,用 Tkinter 搭建了一个简单的图形界面小例子。读完之后手痒,想着能不能拿这个框架做点实际的东西——于是就有了这个公元年份转干支纪年的小计算器。严格来说,一个公元年份并不能和一个干支纪年完全对应(因为一甲子是 60 年,同一个干支对应着多个年份),但作为实用小工具,用来查查常见年份的干支绰绰有余。
公元年份转干支纪年的计算方法
干支基础回顾
先简单回顾一下干支的基础知识。天干有 10 个:
- 甲
- 乙
- 丙
- 丁
- 戊
- 己
- 庚
- 辛
- 壬
- 癸
地支有 12 个:
- 子
- 丑
- 寅
- 卯
- 辰
- 巳
- 午
- 未
- 申
- 酉
- 戌
- 亥
天干计算方法与代码
1984 年是甲子年,这个基准点很关键。天干一共 10 个,年份除以 10 取余数,再做一个偏移就能对上。具体公式:年份 % 10,然后加 6 再模 10,就能从字符串里取到对应的天干。为什么要加 6?因为 1984 的个位数是 4,而 '甲' 在字符串中的索引是 0,(4 + 6) % 10 = 0,正好对上。代码实现如下:
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]
地支计算方法与代码
地支有 12 个,同样用模运算。1984 年是甲子年,而 1984 - 60×30 = 184,184 - 60×3 = 4,所以公元 4 年也是甲子年。利用这个关系,对年份取模 12 后加 8 再模 12,就能得到正确的地支。为什么加 8?4 除以 12 余 4,'子' 的索引是 0,(4 + 8) % 12 = 0,刚好对上。代码:
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]
完整代码实现与运行演示
把上面两个函数和 Tkinter 的界面代码组合起来,就成了下面这样。这个界面参考了 TkDocs 中《A First (Real) Example》的框架,简单实用:
from tkinter import *
from tkinter import ttkdef 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:
passdef 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("", calculate) root.mainloop()
将上述完整代码保存为 ganzhi.py,在终端执行:
python3 ganzhi.py
界面如下:
输入一个正数,例如当前 2026 年,效果如下:
用 1984 年验证:
计算结果与预期完全吻合,这个小工具即可直接使用。
参考资料
- TkDocs tutorial 中的《A First (Real) Example》
