万年历
改代码由DeepSeek生成,准确性未验证
点击查看代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import argparse
from datetime import datetime
# ---------- 日期计算函数 ----------
def is_leap(year):
"""判断是否为闰年"""
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_month(year, month):
"""返回指定年月的天数"""
if month in (4, 6, 9, 11):
return 30
elif month == 2:
return 29 if is_leap(year) else 28
else:
return 31
def days_since_2000(year, month, day):
"""计算从 2000-01-01 到指定日期的天数(不含指定日期当天)"""
days = 0
for y in range(2000, year):
days += 366 if is_leap(y) else 365
for m in range(1, month):
days += days_in_month(year, m)
days += day - 1
return days
def first_day_of_month(year, month):
"""
返回指定月份第一天是星期几
返回值:0=星期日, 1=星期一, ..., 6=星期六
基准:2000-01-01 是星期六(值为6)
"""
diff = days_since_2000(year, month, 1)
return (6 + diff) % 7
# ---------- 打印函数 ----------
def print_month(year, month, title=True):
"""打印单个月份的日历"""
month_names = ['', '一月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '十一月', '十二月']
if title:
print(f"{month_names[month]} {year}".center(20))
print("日 一 二 三 四 五 六")
first_wd = first_day_of_month(year, month)
days = days_in_month(year, month)
# 打印第一行空格
print(" " * first_wd, end="")
for d in range(1, days + 1):
print(f"{d:2d}", end=" ")
if (first_wd + d) % 7 == 0:
print()
if (first_wd + days) % 7 != 0:
print()
def print_year(year):
"""打印整年的日历,每行显示三个月"""
month_names = ['', '一月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '十一月', '十二月']
# 每三个月份为一组
for m in range(1, 13, 3):
# 构造标题行
titles = []
for i in range(3):
mon = m + i
if mon > 12:
break
titles.append(f"{month_names[mon]} {year}".center(20))
print(" ".join(titles))
# 星期行
weeks = ["日 一 二 三 四 五 六"] * len(titles)
print(" ".join(weeks))
# 准备每个月份的行数据
month_lines = []
for i in range(len(titles)):
mon = m + i
first_wd = first_day_of_month(year, mon)
days = days_in_month(year, mon)
lines = []
# 第一行(可能含前导空格)
line = []
for j in range(7):
if j < first_wd:
line.append(" ")
else:
d = j - first_wd + 1
if d <= days:
line.append(f"{d:2d}")
else:
line.append(" ")
lines.append(" ".join(line))
# 后续行
d = 7 - first_wd + 1
while d <= days:
line = []
for j in range(7):
if d <= days:
line.append(f"{d:2d}")
d += 1
else:
line.append(" ")
lines.append(" ".join(line))
month_lines.append(lines)
# 按行输出三个月份的日历
max_rows = max(len(lines) for lines in month_lines)
for row_idx in range(max_rows):
row_parts = []
for lines in month_lines:
if row_idx < len(lines):
row_parts.append(lines[row_idx])
else:
# 用空白填充(长度等于第一行)
row_parts.append(" " * len(month_lines[0][0]))
print(" ".join(row_parts))
print() # 每组之间空一行
# ---------- 命令行入口 ----------
def main():
parser = argparse.ArgumentParser(description="万年历 - 显示公历月份或整年日历")
parser.add_argument("year", nargs="?", type=int, help="年份 (例如 2026)")
parser.add_argument("month", nargs="?", type=int, help="月份 (1-12),若仅指定年份则显示全年")
args = parser.parse_args()
now = datetime.now()
if args.year is None:
# 无参数:显示当前月份
print_month(now.year, now.month)
elif args.month is None:
# 只有年份:显示全年
print_year(args.year)
else:
# 年份 + 月份
print_month(args.year, args.month)
if __name__ == "__main__":
main()

浙公网安备 33010602011771号