Files
rime-ice/lua/lunar.lua
mirtlecn 085ff848dc fix: lunar.db 年份、生肖、繁简错误
- 星期默认置于注释。
- 犬年 => 狗年;按国家标准,干支随生肖更替
- 修正 2051 年星期偏移和数据缺失
2026-04-26 14:46:50 +08:00

86 lines
3.6 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 将今天或者指定的公历日期转换为农历和二十四节气支持1900-2100之间的日期。输入格式为YYYYMMDD例如20240101。
-- 默认格式示例:丙午马年正月初一
-- 标准GB/T 33661-2017 《农历的编算和颁行》GB/T 15835-2011 《出版物上数字用法》4.2.1;参考:人民日报,新华社
-- 数据https://www.hko.gov.hk/tc/gts/time/conversion1_text.htm (注:修正源数据 2051 年星期偏移,修正农历年份偏移)
-- ================================
-- 安装:
-- lunar.lua --> lua/lunar.lua
-- lunar.db --> lua/lunar.db
-- 配置:
-- ```yaml
-- engine/translator:
-- - lua_translator@*lunar
-- recognizer/gregorian_to_lunar: "^N[0-9]{1,8}" # 输入N19700101输出对应的农历信息
-- lunar: lunar # 输入此字符输出今日农历信息
-- lunar_template: "{干支年}{生肖}年{俗称农历月}{农历日}" # 可用字段:{干支年} {农历月} {农历日} {生肖} {俗称农历月} {简记农历日}
-- ```
-- =================================
local lunar_translator = {}
local LUNAR_KEYS = { '干支年', '农历月', '农历日', '星期', '生肖', '节气' }
local function new_lunar_cand( lunar_info, env, seg )
local values = {}
local i = 1
for part in string.gmatch( lunar_info, '[^-]+' ) do
values[LUNAR_KEYS[i]] = part;
i = i + 1
end
values['俗称农历月'] = values['农历月']:gsub( '十二月', '腊月' )
values['简记农历日'] = values['农历日']:gsub( '^二十([一二三四五六七八九])$', '廿%1' )
local args = {}
for _, field in ipairs( env.lunar_template_fields ) do args[#args + 1] = values[field] or '' end
local cand = Candidate(
'lunar', seg.start, seg._end, string.format( env.lunar_format, table.unpack( args ) ),
values['星期']
)
cand.quality = 99999
if values['节气'] then cand.comment = values['星期'] .. ' ' .. values['节气'] end
return cand
end
function lunar_translator.init( env )
local ns = env.name_space:gsub( '^*', '' )
local config = env.engine.schema.config
env.db = ReverseDb( 'lua/lunar.db' )
env.lunar_call_prefix = config:get_string( ns ) or 'lunar'
env.seg_tag = 'gregorian_to_lunar'
local lunar_template = config:get_string( ns .. '_template' ) or
'{干支年}{生肖}年{俗称农历月}{农历日}'
local template_fields = {}
env.lunar_format = lunar_template:gsub(
'{([^}]+)}', function( field )
template_fields[#template_fields + 1] = field
return '%s'
end
)
env.lunar_template_fields = template_fields
end
function lunar_translator.func( input, seg, env )
local date
if input == env.lunar_call_prefix then
date = os.date( '%Y%m%d' )
elseif seg:has_tag( env.seg_tag ) then
date = input:match( '%d+' )
if date and #date < 8 then
yield( Candidate( 'lunar', seg.start, seg._end, '输入完整的日期', 'YYYYMMDD' ) )
return
end
end
if not date then return end
local date_year = tonumber( date:sub( 1, 4 ) )
if date_year > 2100 or date_year < 1900 then
yield( Candidate( 'lunar', seg.start, seg._end, '错误', '仅支持1900-2100之间的日期' ) )
return
end
local lunar_info = env.db:lookup( date )
if lunar_info and #lunar_info > 0 then
yield( new_lunar_cand( lunar_info, env, seg ) )
else
yield( Candidate( 'lunar', seg.start, seg._end, '错误', '未找到对应的农历信息' ) )
end
end
return lunar_translator