cnlunar

repository·master·Indexed 21 days ago

https://github.com/opn48/cnlunar

A high-precision Python 3 library for the Chinese lunar calendar and traditional almanac. Based on the 'Qin Ding Xie Ji Bian Fang Shu' and Hong Kong Observatory data, it provides lunar dates, 24 solar terms, Bazi (Eight Characters), Five Elements, and detailed auspicious/inauspicious activities (宜忌). The library includes data for the 12 Day Officers, 28 Mansions, celestial stems and branches, and various legal and traditional solar and lunar holidays without requiring an external database.

Tokens
5.9K
Snippets
27
Records
29
Agent score
74%

What's inside cnlunar

  1. How cnlunar calculates solar terms and lunar dates

    master
    Unlike many implementations that use the empirical 'Shouxing formula' ([Y*D+C]-L), which can be inaccurate, cnlunar uses data from the Hong Kong Observatory (including the Comparison Table of Gregorian and Lunar Calendars). This ensures high precision for the 24 solar terms and the resulting lunar dates, including leap months and Bazi month pillars. The project avoids using a database by storing compressed solar term and lunar data (using bitwise operations and vector compression) directly within the code.
  2. Quickstart with the Lunar class

    master

    To use cnlunar, import the Lunar class and initialize it with a datetime.datetime object. You can specify the godType parameter to choose between different lunar month algorithms (e.g., '8char' for the standard algorithm used in Bazi/Eight Characters).

    import datetime
    import cnlunar
    
    a = cnlunar.Lunar(datetime.datetime(2022, 11, 14, 10, 30), godType='8char')
    
    # Accessing basic properties
    print(a.lunarYear)
    print(a.lunarMonth)
    print(a.lunarDay)
  3. Determine daily auspicious and inauspicious activities

    master

    The cnlunar library provides logic to calculate the daily 'Good' and 'Bad' things (宜/忌) based on traditional Chinese almanac principles. The calculation involves several steps:

    1. God Identification: It identifies 'Angel' (吉神) and 'Demon' (凶神) gods present on the date.
    2. Initial Classification: It maps these gods to specific activities they favor or forbid.
    3. Conflict Resolution (Thing Leveling): It applies a hierarchy of rules to resolve conflicts when an activity is both favored and forbidden. The thingLevel determines the resolution strategy:
      • 0: 'Follow Good, ignore Bad' (从宜不从忌)
      • 1: 'Follow Good and Bad' (从宜亦从忌)
      • 2: 'Follow Bad, ignore Good' (从忌不从宜)
      • 3: 'Everything is forbidden' (诸事皆忌)
    4. Refinement: It applies specific historical rules (e.g., from the Qinding Xieji Bianfang Shu) to refine the lists, such as removing certain activities if specific gods like 'Tian Gou' (天狗) or specific day branches (like 'Yin' 寅) are present.

    Results are returned as a tuple containing the names of the gods and the lists of activities.

    # The logic follows this pattern of resolving conflicts:
    # 0:'从宜不从忌', 1:'从宜亦从忌', 2:'从忌不从宜', 3:'诸事皆忌'
    
    # Example of the resulting structure (conceptual):
    # ( (goodGodNames, badGodNames), (goodThings, badThings) )
  4. Identify auspicious and inauspicious days (Shen Sha) in cnlunar

    master

    The cnlunar library provides a comprehensive set of traditional Chinese almanac data (Shen Sha/神煞) to determine if a specific day is auspicious (吉) or inauspicious (凶) for various activities.

    Each day is evaluated against several categories of celestial and terrestrial influences, which include:

    • Auspicious (吉) influences: Such as 岁德 (Yearly Virtue), 月德 (Monthly Virtue), 天德 (Heavenly Virtue), 天喜 (Heavenly Joy), 天恩 (Heavenly Grace), 天赦 (Heavenly Pardon), and 吉庆 (Auspicious Celebration).
    • Inauspicious (凶) influences: Such as 岁破 (Yearly Destruction), 月破 (Monthly Destruction), 月煞 (Monthly Sha), 月害 (Monthly Harm), 月刑 (Monthly Punishment), 灾煞 (Disaster Sha), and 大败 (Great Defeat).

    Each influence record typically contains:

    1. Name: The name of the influence (e.g., 天德).
    2. Condition: A boolean or logic check determining if the influence applies to the current date.
    3. Auspicious Activities: A list of recommended actions (e.g., ['祭祀', '祈福', '结婚姻']) if the day is favorable.
    4. Inauspicious Activities: A list of activities to avoid (e.g., ['畋猎', '取鱼']) if the day is unfavorable.

    Developers can use this data to build calendar applications, ritual planning tools, or decision-support systems based on traditional Chinese metaphysics.

  5. Access Lunar calendar and traditional data

    master

    The Lunar object provides a wide range of attributes and methods to retrieve calendar information, including lunar dates, solar terms, Bazi (Eight Characters), and traditional Chinese almanac data (宜忌 - auspicious/inauspicious activities).

    import datetime
    import cnlunar
    
    a = cnlunar.Lunar(datetime.datetime(2022, 11, 14, 10, 30), godType='8char')
    
    dic = {
        '日期': a.date,
        '农历数字': (a.lunarYear, a.lunarMonth, a.lunarDay, '闰' if a.isLunarLeapMonth else ''),
        '农历': '%s %s[%s]年 %s%s' % (a.lunarYearCn, a.year8Char, a.chineseYearZodiac, a.lunarMonthCn, a.lunarDayCn),
        '星期': a.weekDayCn,
        '今日节日': (a.get_legalHolidays(), a.get_otherHolidays(), a.get_otherLunarHolidays()),
        '八字': ' '.join([a.year8Char, a.month8Char, a.day8Char, a.twohour8Char]),
        '今日节气': a.todaySolarTerms,
        '下一节气': (a.nextSolarTerm, a.nextSolarTermDate, a.nextSolarTermYear),
        '今年节气表': a.thisYearSolarTermsDic,
        '季节': a.lunarSeason,
        '今日时辰': a.twohour8CharList,
        '时辰凶吉': a.get_twohourLuckyList(),
        '生肖冲煞': a.chineseZodiacClash,
        '星座': a.starZodiac,
        '星次': a.todayEastZodiac,
        '彭祖百忌': a.get_pengTaboo(),
        '彭祖百忌精简': a.get_pengTaboo(long=4, delimit='<br>'),
        '十二神': a.get_today12DayOfficer(),
        '廿八宿': a.get_the28Stars(),
        '今日三合': a.zodiacMark3List,
        '今日六合': a.zodiacMark6,
        '今日五行': a.get_today5Elements(),
        '纳音': a.get_nayin(),
        '九宫飞星': a.get_the9FlyStar(),
        '吉神方位': a.get_luckyGodsDirection(),
        '今日胎神': a.get_fetalGod(),
        '神煞宜忌': a.angelDemon,
        '今日吉神': a.goodGodName,
        '今日凶煞': a.badGodName,
        '宜忌等第': a.todayLevelName,
        '宜': a.goodThing,
        '忌': a.badThing,
        '时辰经络': a.meridians
    }
  6. Get daily auspicious/inauspicious activities (宜/忌)

    master

    The get_AngelDemon() method calculates traditional 'Auspicious' (宜) and 'Inauspicious' (忌) activities for the day, based on various astrological factors like the 12 Day Officers, solar terms, and zodiac clashes.

    It populates internal attributes:

    • goodGodName / badGodName: Names of auspicious/inauspicious deities.
    • GOOD_THING / BAD_THING: Lists of activities recommended or avoided.

    Additionally, getTodayThingLevel() provides a qualitative assessment of the day's luck (e.g., '上:吉足胜凶' or '下下:凶叠大凶').

    # Get the list of recommended and avoided activities
    # Note: These are populated during get_AngelDemon()
    lunar.get_AngelDemon()
    
    # Get the qualitative luck level
    level_name = lunar.todayLevelName
  7. Get Lunar month phase (Moon phase)

    master

    The getPhaseOfMoon() method returns the traditional Chinese name for the current moon phase based on the lunar day.

    Returns:

    • '望' (Full Moon) if the day is 15 (relative to month length).
    • '朔' (New Moon) if the day is 1.
    • '上弦' (First Quarter) if the day is 7 or 8.
    • '下弦' (Last Quarter) if the day is 22 or 23.
    • '' (Empty string) otherwise.
    phase = lunar.getPhaseOfMoon()
  8. Get Solar Terms (24 JieQi) information

    master

    Retrieve information about the 24 Solar Terms.

    • get_todaySolarTerms(): Returns the name of the solar term occurring on the current date. If no solar term falls on this exact day, it returns '无' (None).
    • thisYearSolarTermsDic: An attribute containing a dictionary mapping solar term names to their dates for the current year.
    term = lunar.get_todaySolarTerms()
    # Access the full year's terms
    terms_dict = lunar.thisYearSolarTermsDic
  9. Get Five Elements and Nayin information

    master

    Retrieve the Five Elements (Wu Xing) and Nayin (纳音) associations for the day.

    • get_nayin(): Returns the Nayin string.
    • get_today5Elements(): Returns a list containing detailed breakdown of the day's elements, including Heavenly Stems, Earthly Branches, and Nayin associations.
    nayin = lunar.get_nayin()
    elements_info = lunar.get_today5Elements()
  10. Get all solar terms for a specific year with getTheYearAllSolarTermsList()

    master

    Use getTheYearAllSolarTermsList(year) to retrieve the complete list of solar terms for a given year. This function retrieves the encoded solar term data from the internal configuration and automatically decompresses it into a usable list. The year parameter should be an integer representing the target year.

    from cnlunar.solar24 import getTheYearAllSolarTermsList
    
    # Get solar terms for the year 2024
    solar_terms = getTheYearAllSolarTermsList(2024)
    print(solar_terms)
  11. Decompress hex solar term data with unZipSolarTermsList()

    master

    The unZipSolarTermsList(data, rangeEndNum=24, charCountLen=2) function decompresses a hexadecimal string or integer representing encoded solar term data into a list of values.

    • data: The hexadecimal string or integer containing the compressed data.
    • rangeEndNum: The number of solar terms to extract (defaults to 24).
    • charCountLen: The bit length used for each entry (defaults to 2).

    It returns a list of solar term values processed via abListMerge.

    from cnlunar.solar24 import unZipSolarTermsList
    
    # Example: Decompressing a hex string
    hex_data = "..."
    solar_terms = unZipSolarTermsList(hex_data)