Skip to content

Instantly share code, notes, and snippets.

@rangercyh
Last active December 18, 2018 08:39
Show Gist options
  • Save rangercyh/841f91f528fdc5dc0ca8 to your computer and use it in GitHub Desktop.
Save rangercyh/841f91f528fdc5dc0ca8 to your computer and use it in GitHub Desktop.
chinese year name calc
--[[
天干纪年,格里历
其实只能正确计算 1752年9月14日之后的,因为1752年9月被英国议会去掉了11天,前面的历法计算需要换用儒略历,太过复杂
]]
local tbHeavenlyStems = { --天干
[1] = "甲",
[2] = "乙",
[3] = "丙",
[4] = "丁",
[5] = "戊",
[6] = "己",
[7] = "庚",
[8] = "辛",
[9] = "壬",
[10] = "癸",
}
local tbEarthlyBranches = { --地支
[1] = "子",
[2] = "丑",
[3] = "寅",
[4] = "卯",
[5] = "辰",
[6] = "巳",
[7] = "午",
[8] = "未",
[9] = "申",
[10] = "酉",
[11] = "戌",
[12] = "亥",
}
local tbFestival = { --春雨惊春清谷天,夏满芒夏暑相连,秋处露秋寒霜降, 冬雪雪冬小大寒
[1] = "立春",
[2] = "雨水",
[3] = "惊蛰",
[4] = "春分",
[5] = "清明",
[6] = "谷雨",
[7] = "立夏",
[8] = "小满",
[9] = "芒种",
[10] = "夏至",
[11] = "小暑",
[12] = "大暑",
[13] = "立秋",
[14] = "处暑",
[15] = "白露",
[16] = "秋分",
[17] = "寒露",
[18] = "霜降",
[19] = "立冬",
[20] = "小雪",
[21] = "大雪",
[22] = "冬至",
[23] = "小寒",
[24] = "大寒",
}
local tbWorldField = {
--[八卦] = { 最通俗的含义,阴阳,五行 }
["乾"] = { "天", "阳", "金" },
["坤"] = { "地", "阴", "地" },
["巽"] = { "风", "阴", "木" },
["震"] = { "雷", "阳", "木" },
["坎"] = { "水", "阳", "水" },
["离"] = { "火", "阴", "火" },
["艮"] = { "山", "阳", "地" },
["兑"] = { "泽", "阴", "金" },
}
local tbFieldMap = {
Heaven = {
['甲'] = { '阳', '木' },
['乙'] = { '阴', '木' },
['丙'] = { '阳', '火' },
['丁'] = { '阴', '火' },
['戊'] = { '阳', '土' },
['己'] = { '阴', '土' },
['庚'] = { '阳', '金' },
['辛'] = { '阴', '金' },
['壬'] = { '阳', '水' },
['癸'] = { '阴', '水' },
},
Earth = {
["子"] = { '阳', '水', '鼠', { 23, 1 }, },
["丑"] = { '阴', '湿土', '牛', { 1, 3 }, },
["寅"] = { '阳', '木', '虎', { 3, 5 }, },
["卯"] = { '阴', '木', '兔', { 5, 7 }, },
["辰"] = { '阳', '湿土', '龙', { 7, 9 }, },
["巳"] = { '阴', '火', '蛇', { 9, 11 }, },
["午"] = { '阳', '火', '马', { 11, 13 }, },
["未"] = { '阴', '燥土', '羊', { 13, 15 }, },
["申"] = { '阳', '金', '猴', { 15, 17 }, },
["酉"] = { '阴', '金', '鸡', { 17, 19 }, },
["戌"] = { '阳', '燥土', '狗', { 19, 21 }, },
["亥"] = { '阴', '水', '猪', { 21, 23 }, },
},
}
local function get_year_he(zero_above, year)
local h = math.fmod(year, 10)
local e = math.fmod(year, 12)
local stem = zero_above and (h>3 and h-3 or h+7) or (h<8 and 8-h or 18-h)
local branch = zero_above and (e>3 and e-3 or e+9) or (e<10 and 10-e or 22-e)
return tbHeavenlyStems[stem], tbEarthlyBranches[branch]
end
local function get_month_he(year, month)
local month_first_branch = 3 -- 夏历,正月建寅
local m_h = (math.fmod(year, 5) - 2) * 2 - 1
m_h = m_h < 0 and m_h + 10 or m_h
m_h = math.fmod(m_h+month-1, 10)
m_h = m_h == 0 and 10 or m_h
local m_e = math.fmod(month_first_branch+month-1, 12)
m_e = m_e == 0 and 12 or m_e
return tbHeavenlyStems[m_h], tbEarthlyBranches[m_e]
end
local function get_day_he(zero_above, year, month, day)
local span_month = month
local span_year = year
if month == 1 or month == 2 then
span_year = zero_above and year - 1 or year + 1
span_year = span_year == 0 and 1 or span_year
span_month = span_month + 12
end
local C = math.ceil(span_year/100)
C = zero_above and C or -1*(C-1)
C = C - 1
local i = math.fmod(span_month, 2) > 0 and 0 or 6
local y = math.fmod(span_year, 100)
local gz = 44*C + math.floor(C/4) + 5*y + math.floor(y/4) +
30*(span_month+1) + math.floor(3*(span_month+1)/5) + day + 7
local d_h = math.fmod(gz, 10)
d_h = d_h == 0 and 10 or d_h
local d_e = math.fmod(gz, 12)
d_e = d_e == 0 and 12 or d_e
return tbHeavenlyStems[d_h], tbEarthlyBranches[d_e]
end
function GetTimeInfo(year, month, day, hour, min, sec)
if year then assert(math.type(year) == 'integer' and year ~= 0) end
if month then assert(math.type(month) == 'integer' and month > 0 and month <= 12) end
if day then assert(math.type(day) == 'integer' and day > 0 and day <= 31) end
if hour then assert(math.type(hour) == 'integer' and hour > 0 and hour <= 23) end
if min then assert(math.type(min) == 'integer' and min > 0 and min <= 59) end
if sec then assert(math.type(sec) == 'integer' and sec > 0 and sec <= 59) end
local time = os.date("*t")
year = year or time.year
local zero_above = year > 0
year = zero_above and year or -year
-- 干支纪年
local H, E = get_year_he(zero_above, year)
local M_H, M_E, D_H, D_E
-- 干支纪月
if month then
M_H, M_E = get_month_he(year, month)
-- 干支纪日
if day then
D_H, D_E = get_day_he(zero_above, year, month, day)
end
end
return string.format('%s%s年%s%s', H, E,
M_H and string.format('%s%s月', M_H, M_E) or '',
D_H and string.format('%s%s日', D_H, D_E) or '')
end
print(GetTimeInfo(2018))
print('2049年', GetTimeInfo(2049))
print('1912年2月', GetTimeInfo(1912, 2))
print('1912年2月18日', GetTimeInfo(1912, 2, 18))
print('1年1月1日', GetTimeInfo(1, 1, 1))
print('公元前1年1月1日', GetTimeInfo(-1, 1, 1))
print('公元前1年10月1日', GetTimeInfo(-1, 10, 1))
print('公元前2年10月1日', GetTimeInfo(-2, 10, 1))
print('公元前211年11月1日', GetTimeInfo(-211, 11, 1))
print('公元前720年2月22日', GetTimeInfo(-720, 2, 22))
print('2018年11月12日', GetTimeInfo(2018, 11, 12))
print('1987年7月18日', GetTimeInfo(1987, 7, 18))
print('1997年1月15日', GetTimeInfo(1997, 1, 15))
print('2008年8月8日', GetTimeInfo(2008, 8, 8))
print('2015年11月21日', GetTimeInfo(2015, 11, 21))
print('2016年2月14日', GetTimeInfo(2016, 2, 14))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment