1. 程式人生 > >風火程式設計--干支紀年法的完整轉換(可用於八字推算)

風火程式設計--干支紀年法的完整轉換(可用於八字推算)

嚴謹的干支紀年法轉換

干支紀年法的年,月分界點與公曆不同, 因此單純的使用公曆日期轉換,得到的結果必然有一部分是錯誤的. 目前通用的解決方案是使用資料庫儲存幾百年的資料,然後通過查庫實現. 本程式已經考慮了以上內容, 節氣時間通過爬蟲獲取,沒有資料庫操作.
需要的加個粉點個贊, 直接拿走. 厚道人, 不要那幾個垃圾幣了.
歡迎討論, 本人qq及微訊號碼:77245741

完整原始碼奉上

# coding: utf-8

import re
from math import ceil
from datetime import datetime

import requests
from lxml import etree
tg = '癸甲乙丙丁戊己庚辛壬'  # 天干字串
dz = '亥子醜寅卯辰巳午未申酉戌'  # 地址字串

def to_ganzhi(year, mon, day, hour=1, min=1, sec=1):
    """
    干支紀年轉換
    :param year: 公曆年, int 2018
:param mon: 公曆月, int 1
:param day: 公曆日, int 1
:param hour: 24進位制小時, int 1
:param min: 分鐘, int 1
:param sec: 秒, int 1
:return: 干支紀年法表示的時間, xx年xx月xx日xx時
    """
    date_time = datetime.strptime(
        "{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}".format(year, mon, day, hour, min, sec), "%Y-%m-%d %H:%M:%S")
        
    lichun = get_jieqi(year)
    jieqi = get_jieqi(year, mon)

    year4compute = year - 1 if date_time < lichun else year
    mon4compute = (mon + 11) % 12 if date_time < jieqi else mon
    # 年干支
    year_g = (year4compute+7) % 10  # 年幹
    year_z = (year4compute + 9) % 12  # 年支
    
    # 月干支
    mon_g = (year % 5*2 + mon4compute + 3) % 10  # 月幹
    mon_z = (mon4compute + 1) % 12  # 月支

    # 日干支
    date_init = datetime.strptime("0001-01-05", "%Y-%m-%d")
    date = datetime.strptime("{}-{:0>2}-{:0>2}".format(year, mon, day), "%Y-%m-%d")
    dete = (date - date_init).days
    dete4compute = dete + 1 if hour >= 23 else dete

    day_g = dete4compute % 10  # 日干
    day_z = (dete4compute + 8) % 12  # 日支

    # 時干支
    hour_g = int((dete4compute % 5 * 2 + ceil(hour/2) + 9) % 10)  # 時幹
    hour_z = int((ceil(hour/2) + 1) % 12)  # 時支

    print("args_g", year_g, mon_g, day_g, hour_g)
    print("args_z", year_z, mon_z, day_z, hour_z)
    print(type(hour_z))

    gz = "{}{}年  {}{}月 {}{}日 {}{}時".format(
        tg[year_g],
        dz[year_z],
        tg[mon_g],
        dz[mon_z],
        tg[day_g],
        dz[day_z],
        tg[hour_g],
        dz[hour_z]
        )
    print(gz)


def get_jieqi(start_year, mon=2, limit=1):
    """
    獲取節氣時間, 如果要存庫,可以傳入limit引數
    ::param start_year:  起始年份
:param limit:需要獲取的年數
:return: 資料生成器
    """
    jieqi = {
        2: "lichun",
        3: "jingzhe",
        4: "qingming",
        5: "lixia",
        6: "mangzhong",
        7: "xiaoshu",
        8: "liqiu",
        9: "bailu",
        10: "hanlu",
        11: "lidong",
        12: "daxue",
        1: "xiaohan"
    }

    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"}

    if limit == 1:
        url = "https://jieqi.51240.com/%d_%s__jieqi/" % (start_year, jieqi[mon])
        response = requests.get(url=url, headers=headers)
        html = etree.HTML(response.text)
        ret = html.xpath('//div[@class="jieqi_neirong_biaoti_beizhu"]/strong/text()')[0]
        data = re.sub(r"[年月]", "-", ret).replace("日", "")
        time_data = datetime.strptime(data, "%Y-%m-%d %H:%M:%S")
        print(time_data, type(time_data))
        return time_data
    else:
        time_list = []
        urls = ("https://jieqi.51240.com/%d_lichun__jieqi/" % year for year in range(
            start_year, start_year + limit))
        for url in urls:
            response = requests.get(url=url, headers=headers)
            html = etree.HTML(response.text)
            ret = html.xpath('//div[@class="jieqi_neirong_biaoti_beizhu"]/strong/text()')[0]
            data = re.sub(r"[年月]", "-", ret).replace("日", "")
            time_data = datetime.strptime(data, "%Y-%m-%d %H:%M:%S")
            print(time_data, type(time_data))
            time_list.append(time_data)
        time_gen = iter(time_list)
        year_gen = range(start_year, start_year + limit)
        return year_gen, time_gen

if __name__ == '__main__':
    to_ganzhi(2013, 12, 2, 23, 11, 10)  # 示例