Lunisolar
Typescript农历库,支持阴历公历互转,支持各类黄历数据查询,如八字四柱、阴历、神煞宜忌、建除十二神、胎神占方、吉神方位、五行纳音等。支持自定义插件。
Install / Use
/learn @waterbeside/LunisolarREADME
【线上文档请点这里】
lunisolar 是一个使用Typescript编写的专业农历库, 可取得各类农历数据,参考中国中代书籍,数据来源有依有据。支持多语言(可自定义语言包),支持自定义插件。
具体包含以下功能:
- ✅公历-阴历互转
- ✅阴历查询
- ✅八字查询
- ✅节气日期查询
- ✅Markers(日期备注、节日功能)
- ✅胎神占方 (插件)
- ✅五行纳音 (插件)
- ✅神煞系统 (插件) <基于:协纪辨方书>
- ✅建除十二神
- ✅神煞宜忌
- ✅时辰凶吉
- ✅八字增强 (插件)
- ✅八字十神
- ✅四柱神煞
- ⏳~~紫微斗数~~ (planning)
- ...更多功能开发中
- 快速上手
- 前言
- 1 安装
- 2 解释 (创建Lunisolar对象)
- 3 Lunisolar类
- 4. 阴历数据
- 5 八字(天干地支)
- 6 节气
- 7 胎神
- 8 纳音
- 9 建除十二神
- 10 神煞宜忌
- 11 日期备注 Markers
- 插件 plugins
- 国际化
- 支持
快速上手
// 引入
import lunisolar from 'lunisolar'
// 使用
const d = lunisolar('2022/07/18 14:40')
// --- format ---
d.format('lY年 lM(lL)lD lH時') // 可取得阴历日期 '二〇二二年 六月(大)二十 未時'
d.format('cY cM cD cH') // 可取得八字:'壬寅 丁未 壬申 丁未'
d.format('YYYY-MM-DD HH:mm:ss') // 2022-07-18 14:40:00
// --- 阴历---
d.lunar.toString() // 二〇二二年六月二十未時
`${d.lunar}` // 二〇二二年六月二十未時
d.lunar.year // 2022
d.lunar.getYearName() // 二〇二二
d.lunar.month // 6 (如果是闰六月会返回106)
d.lunar.getMonthName() // 六月
d.lunar.day // 20
d.lunar.getDayName() // 二十
d.lunar.hour // 7 (返回从0开始算的时辰下标)
d.lunar.getHourName() // 未
d.lunar.isLeapMonth // false (是否闰月)
// --- 八字 ----
`${d.char8}` // 壬寅 丁未 壬申 丁未
d.char8.year.toString() // 壬寅 (取得年柱)
d.char8.month.toString() // 丁未 (取得月柱)
d.char8.day.toString() // 壬申 (取得日柱)
d.char8.hour.toString() // 丁未 (取得时柱)
d.char8.year.stem.toString() // 壬 (年柱天干)
d.char8.year.branch.toString() // 寅 (年柱地支)
d.char8.year.branch.hiddenStems // [甲, 丙, 戊] (地支藏干的天干对象列表,顺序为本气、中气、余气)
// ...其它柱类似
// 节气
lunisolar('2022-07-23').solarTerm?.toString() // 大暑 (返回当天的节气,如果不是节气则solarTerm().solarTerm返回null)
// 阴历反查 (阴历转公历)
lunisolar.fromLunar({
year: 2022,
month: 10,
day: 25
}).format('YYYY-MM-DD') // 2022-11-18
前言
* 为何制作此库
昔见不同版本日历(包括纸质日历和各类日历软件),其所示宜忌有所不同,更有相矛盾者,不知如何取用,故疑其推算依据是否误,本着宏扬传统文化之精神,离所有职务,查阅各资料文案,以制此库。
* 阴历和阳历
现所用的中国传统历法,我们常称为农历,农历是阴阳合历,即包含了阴历和阳历,所以此库命名为lunisolar。
农历中,通过月相圆缺纪月,此属于阴历范畴,本库会以一个Lunar对象记录转换好的阴历数据。
而公历与阴历的转换没规律可言,故采用查表法进行转换,其数据来自香港天文台【公历与农历日期对照表】。其可查询年份范围为[1901,2100]。数据抓取和压缩的代码见仓库 lunar-crawler,此处不作详细介绍。
属于阳历范畴的内容比较多,有二十四节气、天干地支等,传统很多术数多以阳历排盘,如八字、奇门遁甲...(也有少数以阴历排盘的,如紫微斗数)。其中二十四节气是阳历中十分重要的部分,其影响天干地支的换岁和换月。
* 年和岁
在传统上,年和岁是两个不同的概念。
年 是指阴历正月初一到下一个正月初一的一个周期。
岁 是指太阳连续两次通过春分点的时间间隔,古人一般用‘冬至点’来观测,现代称作回归年(tropical year),也叫 太阳年(solar year)。一个周期结束而开始下一个周期,称为换岁。
$$1回归年 = 365.2421990741日 = 365天5小時48分46秒$$
* 节和气
我们常说的二十四节气,其实分为节和气两种,共十二节和十二气,节和气交替出现。天干地支纪月是以节换月的。
| | | | 节 | 气 | | --- | --- | --- | --- | --- | | | 孟春 | 寅月 | 立春 | 雨水 | | 春 | 仲春 | 卯月 | 惊蛰 | 春分 | | | 季春 | 辰月 | 清明 | 谷雨 | | | 孟夏 | 巳月 | 立夏 | 小满 | | 夏 | 仲夏 | 午月 | 芒种 | 夏至 | | | 季夏 | 未月 | 小暑 | 大暑 | | | 孟秋 | 申月 | 立秋 | 处暑 | | 秋 | 仲秋 | 酉月 | 露水 | 秋分 | | | 季秋 | 戌月 | 寒露 | 霜降 | | | 孟冬 | 亥月 | 立冬 | 小雪 | | 冬 | 仲冬 | 子月 | 大雪 | 冬至 | | | 季冬 | 丑月 | 小寒 | 大寒 |
实际上,节气是某一个时刻,而这个时刻并不是固定在某天的某个时辰。但由于数据源只精确到日,所以本库的交节(更换八字月柱),也是以日为准。
* 生肖和换岁
我们知道天干地支是基于二十四节气来定的。在民间,如八字命理这类术数,通常以立春换岁,即到了立春,便更换下一个天干地支纪年,例如今年为甲子年,则到下一个立春,则换成乙丑年。
但是,并不是所有术数都是以立春换岁,例如中医的五运六气,则以大寒日换岁。 而奇门遁甲则以冬至换岁,中气换月。
lunisolar默认使用立春换岁, 当然你也可以自定义换岁的节气。
生肖:生肖与十二地支是对应的,所以实际上生肖也是按节气更换,而不少传统述数系统都是以立春换岁,所以生肖应当也是按立春更换。
但是,跟据 中国大陆国家标准:编号**GB/T 33661-2017 《农历的编算和颁行》**规定,
“干支纪年的循环参考时间:对应于北京时间公历1984年2月2日0时起到1985年2月19日24时截止的农历年为甲子年。”
如按此标准的话,应该正月初一换岁,即生肖在正月初一更换。 这与传统术数的计算方式有所冲突,也许是为了方便大众记忆与使用。 由于大部分术数系统并不以正月初一换岁,所以lunisolar默认并不跟随此标准进行换岁(虽然可以通过配置设置成与国标一致,但不建议)。
* 换日
传统子时是每一天的开始,子时对应的时间为 [23:00, 01:00), 所以lunisolar会在23:00进行换日。
* 其它
moment.js 和 dayjs 是两个比较出名的时间工具库,为了符合大家的使用习惯,lunisolar针对公历的部分操作将会尽量向dayjs看齐,并参考了其代码设计。针对公历部分,尽管lunisolar也有类似dayjs的方法,但并不会cover其所有功能,如果你仅仅是对公历进行操作,推荐使用dayjs。lunisolar重点在于农历部分,例如Lunisolar的format方法和diff方法包含dayjs这两个方法的功能并与之保持一致,同时加入了对农历的处理,具体功能及使用请继续阅读文档。
1 安装
1.1 Nodejs
npm install lunisolar
# or
yarn add lunisolar
引入
import lunisolar from 'lunisolar'
如果你使用typescript你需要设置:
{ //tsconfig.json
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
}
}
否则你必需这样引入:
import * as lunisolar from 'lunisolar'
1.2 浏览器直接通过script引入
<script src="path/to/lunisolar.js"></script>
<!-- or src from unpkg ( 请根据需求选择版本号 ↓ )-->
<script src="https://unpkg.com/lunisolar@2.1.12/dist/lunisolar.js"></script>
2 解释 (创建Lunisolar对象)
2.1 解释 (Parse)
通过lunisolar函数创建一个Lunisolar实例对象:
lunisolar(param: String | Number | Date | Lunisolar, config?: ConfigType): Lunisolar
// 传入字符串
lunisolar('2022-07-18 14:40')
lunisolar('2022/07/18')
// 不传入参数时,为当前时间
lunisolar()
// 传入时间戳 (毫秒为单位)
lunisolar(1658289207143)
// 传入Date对象
lunisolar(new Date(2022, 6, 20))
// 传入Lunisolar对象时,将克隆一个Lunisolar对象
lunisolar(lunisolar())
//
const config = {
lang: 'en' // 更改用语言,需先加载对应语言包,详见文档 【国际化】的说明
}
lunisolar('2022-07-18 14:40', config)
2.2 克隆 Lunisolar 实例对象
const lsr1 = lunisolar('2022-07-18 14:40')
const lsr2 = lsr1.clone()
2.3 阴历反查
通过阴历数据创建一个Lunisolar实例对象,此法可用来阴历转公历:
lunisolar.fromLunar(lunarData: LunarData, config: ConfigType): Lunisolar
参数说明
lunarData: LunarData
type LunarData = {
year?: number | string
// 该年正月初一所在公历年的年份,可以是字符串,默认值为当前日期的年份
month: number | string
// 阴历月份,可以是字符串,必填, 当月份数大于100时,表明时闰月,如闰4月,可输入104
day: number | string
// 阴历日,可以是字符串,必填
hour?: number | string
// 时辰索引值或时辰名,默认为0, 即子时。设置时辰后,返回的小时为该时辰的中间时间,如寅时,会返回4点正的时间。
isLeapMonth?: boolean
// 指明月份是否闰月,默认为false, 当month设为大于100的数时,会无视此设置
}
示例1
const lunarData = {
year: 2022,
month: 10,
day: 25
}
const lsr = lunisolar.fromLunar(lunarData) // 成功创建一个个Lunisolar实例对象
console.log(lsr.format('YYYY-MM-DD')) // 2022-11-18
示例2
你也可以使用汉字进行阴历反查
// lunisolar默认使用繁体中文语言包,此语言包默认自动加载,可直接使用繁体中文
// 使用其它语言包参考示例3
const lunarData = {
year: '二〇二〇',
month: '閏四月',
day: '廿四'
}
const lsr = lunisolar.fromLunar(lunarData) // 成功创建一个个Lunisolar实例对象
console.log(lsr.format('YYYY-MM-DD')) // 2020-06-15
示例3
使用简体中文进行阴历反查
import lunisolar from 'lunisolar'
import zhCn from 'lunisolar/locale/zh-cn'
import ja from 'lunisolar/locale/ja'
lunisolar.locale(ja) // 加载日文语言包
lunisolar.locale(zhCn) // 加载简体中文语言包,最后加载者,会全局默认使用该语言包
const lunarData = {
year: '二〇二〇',
month: '闰四月', // 此时,如果还是使用繁体的“閏”字会报错。
day: '廿四'
}
const lsr = lunisolar.fromLunar(lunarData) // 成功创建一个个Lunisolar实例对象
console.log(lsr.format('YYYY-MM-DD')) // 2020-06-15
// lunisolar.locale(zhCn) 加载简体中文语言名后,会全局使用zh-cn语言包
// 如果个别实例想使用其它语言包可通config进行临时更改,如使用日文,
const lsr2 = lunisolar.fromLunar({
year: '二〇二〇',
month: '睦月',
day: '一日'
}, {
lang: 'ja' // 指正要使用的语言包名
})
console.log(lsr.format('YYYY-MM-DD')) // 2020-01-25
3 Lunisolar类
通过lunisolar()函数获得一个Lunisolar实例
Lunisolar具有以下属性和方法
| 属性或方法 | 描述 | 参数 | 返回类型 | | --- | --- | --- | --- | | lunar | 阴历数据对象 | | Lunar | | char8 | 八字对象 | | Char8 | | solarTerm | 返回当前日期的节气对象,如果不是节气,返回null | | SolarTerm | null | | getSeason() | 取得当前季节 | | string | | getSeasonIndex() | 以春夏秋冬为顺序取得当前季节索引 | | number | | toDate() | 返回Date对象 | | Date | | clone() | 克隆当前Lunisolar对象 | | Lunisolar | | unix() | 返回以秒为单位的时间戳 | | number | | format(formatStr: string) | 按指定格式格式化时间 | formatStr: string 时间将以这字符串格式进行格式化,例 'YYYY-MM-DD HH:mm:ss' | string | | diff(date, unit, float) | 时间差计算 | date: number | string | Date | Lunisolar <br> 与当前实例的时间进行比较的时间<br> unit: string <br>单位,如 year, lunarYear, month, lunarMonth 等<br> float: boolean <br>是否返回浮点数 | number | | add(value, unit) | 时间加减 | value: number 时间加减的值,负数为减 <br/> unit: string 加减单位 | number | | year | 年份 | | number | | month | 月份 1 ~ 12 | | number | | day | 日期 1 ~ 31 | | number | | dayOfWeek | 周几,0 ~ 6, 0代表周日 | | number | | hour | 小时 0 ~ 23 | | number | | minute | 分 0 ~ 59 | | number | | second | 秒 0 ~ 59 | | number | | millis | 毫秒 0 ~ 999 | | number | | utc() | 转为utc模式 | | Lunisolar | | isUTC() | 检查是否为UTC模式的实例 | | boolean | | utcOffset(offset) | 取得,或设置utc偏移值 | offset: number | undefined <br/> · 当为undefined时,为取得utc偏移值, 返回单位为分钟的number值 <br /> · 当为number类型时,为设置utc偏移值,并把时间转为utc时间,返回一个新的Lunisolar实例。如果设置的offset范围在[-16, 16], 则单位为小时,其它情况为分钟 | Lunisolar | number | | local() | 转为本地时间 | | Lunisolar | | valueOf() |
