├── .gitignore ├── LICENSE ├── README.md ├── ReName.py ├── db └── data.zip └── lib ├── DB.py ├── __init__.py └── boxcalendar.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | .idea 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Cooper Pei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReName 2 | Python 3.6.4编写的使用中国古代古诗词起名字的程序,囊括13个朝代12,873名作者的共190,150首诗、词、诗经。 3 | 根据姓氏、性别、出生年月日时参数获取相应五行互补的名字,随机获得五组名字及诗词出处。 4 | 5 | ## 设计思路 6 | 通过阳历生辰年/月/日/时转换得到的农历生辰计算对应的八字,再将八字转换为五行,依据五行平衡的原理算出五行缺失,而后将诗词内容分词得到的双字(新生 7 | 儿起名不再接受单字名)依据汉字的“金木水火土”五行取得缺失五行对应的双字词语,作为最终的名字,通过1518测名网(1518.com)评分,选取分数超过95分的5组结果输出,同时输出该名字的出处。 8 | 并从国人姓名常用字中筛选对应的分词组合,以避免意义不吉利的词。 9 | 10 | 为确保名字出处的唯一性,分词结果去掉了数量超过1个的词语,如,以下是古诗词中出现频率最高的前18组词语: 11 | * 何处(847次) 12 | * 不知(791次) 13 | * 春风(715次) 14 | * 万里(688次) 15 | * 青山(640次) 16 | * 东风(629次) 17 | * 明月(605次) 18 | * 风雨(587次) 19 | * 不见(556次) 20 | * 江南(549次) 21 | * 秋风(545次) 22 | * 人间(538次) 23 | * 千里(535次) 24 | * 不可(520次) 25 | * 归来(499次) 26 | * 白云(495次) 27 | * 桃花(471次) 28 | * 夕阳(463次) 29 | 30 | ## 程序说明 31 | * ReName.py: 从古诗词分词结果中依据八字五行随机获取候选名字的程序。 32 | * lib/DB.py: 爬虫、分词程序进行存储的数据库操作程序。 33 | * lib/boxcalendar.py: 修改[https://github.com/ccdjh/boxcalendar](https://github.com/ccdjh/boxcalendar) 模块的程序,去掉了不必要的程序和输出,用于转换阳历生辰为农历。 34 | * db/data.sql: 数据库结构SQL,包括诗词、分词、名字常用词在内的所有表结构及数据。 35 | 36 | ## 操作说明 37 | > python ReName.py -s 赵 -g M -y 2018 -m 7 -d 1 -H 17 38 | ``` 39 | [*] 出生日期:2018年7月1日, 17时 40 | [*] 五行属性:土, 火 41 | 42 | [-] 候选名字:赵护少 43 | [-] 名字出处: 44 | 《和之美舟行杂诗八首·罾鱼者》 45 | 司马光(宋) 46 | 弱绦絓轻丝,尽日寒溪侧。护少近知无,溪鱼皆尔识。 47 | 48 | [-] 候选名字:赵信雁 49 | [-] 名字出处: 50 | 《龟堂独酌》 51 | 陆游(宋) 52 | 一榼兰溪自献酬,徂年不肯为人留。巴山频入初寒梦,江月偏供独夜愁。越石壮心鸡喔喔,子卿归信雁悠悠。天生我辈初何用,病骨支离又过秋。 53 | 54 | [-] 候选名字:赵常尊 55 | [-] 名字出处: 56 | 《上丞相平淮颂》 57 | 邢凯(宋) 58 | 皇矣圣宋,立国以仁。兼爱南北,肤暨介鳞。蠢芘逆全,假义俫臣。给以餽餫,列之簪绅。鹰饱别剔,浸无忌惮。边臣戕贼,居民涂炭。据我监城,喻口植干。继逼海陵,恣为泮奂。玺书飞下,皇威赫然。声罪致讨,仇激普天。许之节铖,副以金钱。奋忠效命,谁不争先。粤有世臣,虏使元帅。罗致英才,虓将云会。贾勇摧锋,前无坚对。逆全授首,信阳城外。昔淮蔡惟断成功。至平泽潞,伐谋群雄。圣君贤相,视昔则同。山水阳膻,一洗而空。钜伏就不,殊方仰德。鲸波不惊,狼烟永息。男耕女桑,四民安职。玉烛即调,金穰可必。圣君贤相,益固本根。广求民瘼,博尽忠言。屏除贪吏,澄浴治源。狂谋不起,国势常尊。一介微官,尝玷策府。颂我君相,或占古语。於万斯年,受天之佑。锡公纯虾,眉寿何鲁。 59 | 60 | [-] 候选名字:赵续开 61 | [-] 名字出处: 62 | 《病起幽园检校》 63 | 周弼(宋) 64 | 病起无情绪,池边日几回。虫声低覆草,螺壳细生苔。暑退芦将变,秋残蓼续开。久消环绕迹,全若未尝来。 65 | 66 | [-] 候选名字:赵强说 67 | [-] 名字出处: 68 | 《予去杭十六年而复来留二年而去平生自觉出处》 69 | 苏轼(宋) 70 | 以丑石赠行作三绝句当年衫鬓两青青,强说重临慰别情。衰发只今无可白,故应相对话来生。出处依稀似乐天,敢将衰朽较前贤。便従洛社休官去,犹有闲居二十年。在郡依前六百日,山中不记几回来。还将天竺一峰去,欲把云根到处栽。 71 | ``` -------------------------------------------------------------------------------- /ReName.py: -------------------------------------------------------------------------------- 1 | try: 2 | from bs4 import BeautifulSoup 3 | except ImportError: 4 | print("[!_!]ERROR INFO: You have to install bs4 module.") 5 | exit() 6 | 7 | try: 8 | import requests 9 | except ImportError: 10 | print("[!_!]ERROR INFO: You have to install requests module.") 11 | exit() 12 | 13 | try: 14 | import ngender 15 | except ImportError: 16 | print("[!_!]ERROR INFO: You have to install ngender module.") 17 | exit() 18 | 19 | import argparse 20 | import sys 21 | import signal 22 | from random import randint 23 | from lib.DB import DBOP 24 | from lib.boxcalendar import * 25 | 26 | SCORE_LINE = 95 27 | 28 | 29 | def compute_wuxing(year, month, day, hour): 30 | horoscope = lunarday(year, month, day) 31 | day_stem = horoscope[2].split('-')[2][0] 32 | 33 | time_stem_branch_list = [ 34 | [u"甲子",u"丙子", u"戊子", u"庚子", u"壬子"], 35 | [u"乙丑",u"丁丑", u"己丑", u"辛丑", u"癸丑"], 36 | [u"丙寅",u"戊寅", u"庚寅", u"壬寅", u"甲寅"], 37 | [u"丁卯",u"己卯", u"辛卯", u"癸卯", u"乙卯"], 38 | [u"戊辰",u"庚辰", u"壬辰", u"甲辰", u"丙辰"], 39 | [u"己巳",u"辛巳", u"癸巳", u"己巳", u"丁巳"], 40 | [u"庚午", u"壬午",u"甲午", u"丙午", u"戊午"], 41 | [u"辛未",u"癸未", u"乙未", u"丁未", u"己未"], 42 | [u"壬申",u"甲申", u"丙申", u"戊申", u"庚申"], 43 | [u"癸酉",u"乙酉", u"丁酉", u"己酉", u"辛酉"], 44 | [u"甲戌",u"丙戌", u"戊戌", u"庚戌", u"壬戌"], 45 | [u"乙亥",u"丁亥", u"己亥", u"辛亥", u"癸亥"] 46 | ] 47 | sky_branch = [u'甲', u'乙', u'丙', u'丁', u'戊', u'己', u'庚', u'辛', u'壬', u'癸'] 48 | 49 | index = 0 50 | for index in range(10): 51 | if day_stem == sky_branch[index]: 52 | break 53 | 54 | index_X = index - 5 if index >= 5 else index 55 | index_Y = int((hour + 1) / 2) 56 | 57 | # Generate horoscope 58 | horoscope = horoscope[2] + '-' + time_stem_branch_list[index_Y][index_X] 59 | 60 | wuxing_dic = { 61 | u"金": [u"申", u"酉", u"庚", u"辛"], 62 | u"木": [u"寅", u"卯", u"甲", u"乙"], 63 | u"水": [u"子", u"亥", u"壬", u"癸"], 64 | u"火": [u"巳", u"午", u"丙", u"丁"], 65 | u"土": [u"辰", u"戌", u"丑", u"未", u"戊", u"己"] 66 | } 67 | wuxing = {} 68 | horoscope_list = list(''.join(horoscope.split('-'))) 69 | for key, value in wuxing_dic.items(): 70 | count = 0 71 | for item in horoscope_list: 72 | if item in value: 73 | count += 1 74 | wuxing[key] = count 75 | return wuxing 76 | 77 | 78 | def name_score(name, sur_type=1): 79 | """ 80 | Get number of name from 1518.com 81 | :param name: full name 82 | :param sur_type: surname single(1) or double(2) 83 | :return: name score 84 | """ 85 | header = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 86 | 'Accept-Encoding': 'gzip, deflate', 87 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 88 | 'User-Agent': 'Chrome/63.0.3239.84 Safari/537.36' 89 | } 90 | name = str(name.encode('gbk')).split("'")[1].replace('\\x', '%') 91 | name_url = 'http://m.1518.com/xingming_view.php?word={}&submit1=&FrontType={}' 92 | page_html = requests.get(name_url.format(name, sur_type), headers=header) 93 | page_html = page_html.content 94 | parse_file = BeautifulSoup(page_html, 'lxml') 95 | name_score = parse_file.select('dt > u strong') 96 | try: 97 | score = name_score[0].text.split('分')[0] 98 | except IndexError: 99 | score = 0 100 | finally: 101 | score = int(score) 102 | return True if score > SCORE_LINE else False 103 | 104 | 105 | def output_wuxing(year, month, day, hour): 106 | """ 107 | Compute WuXing with birth datetime. 108 | :param year: 109 | :param month: 110 | :param day: 111 | :param hour: 112 | :return: attribute list 113 | """ 114 | wuxing = compute_wuxing(year, month, day, hour) 115 | print("[*] 出生日期:%s年%s月%s日, %s时" % (year, month, day, hour)) 116 | attr_list = [attr for attr in wuxing if wuxing[attr] < 2] 117 | name_attr = list(set(['金', '木', '水', '火', '土']) - set(attr_list)) 118 | print("[*] 五行属性:%s\n" % ', '.join(name_attr)) 119 | return attr_list 120 | 121 | 122 | def filter_name(surname, gender, attr): 123 | """ 124 | Filter names with gender, general name word and name score. 125 | :param surname: surname of name. 126 | :param gender: gender of name. 127 | :param attr: attribute list of name. 128 | :return: None 129 | """ 130 | sur_type = 1 if len(surname) == 1 else 2 131 | db_obj = DBOP() 132 | name_tuple = db_obj.get_wuxing_name(attr) # Get all match words 133 | match_count = 0 134 | while 1: 135 | if match_count == 5: 136 | break 137 | name_info = name_tuple[randint(0, len(name_tuple))] 138 | name_id, name = name_info[0], name_info[1] 139 | full_name = surname + name 140 | # Match gender and general name word. 141 | if gender != ngender.guess(full_name)[0][0].upper() or not db_obj.match_name_word(name): 142 | continue 143 | if not name_score(full_name, sur_type): 144 | continue 145 | print("[-] 候选名字:%s" % full_name) 146 | match_count += 1 147 | name_source = db_obj.get_name_source(name_id) 148 | print("[-] 名字出处:") 149 | print(name_source[2]) 150 | print(name_source[1] + '(' + name_source[0] + ')') 151 | print(name_source[3]) 152 | print('\n') 153 | 154 | 155 | def sigint_handler(signum, frame): 156 | print('You pressed the Ctrl+C.') 157 | sys.exit(0) 158 | 159 | 160 | if __name__ == '__main__': 161 | signal.signal(signal.SIGINT, sigint_handler) 162 | 163 | parser = argparse.ArgumentParser(description="Name children with birth datetime and WuXing balance.") 164 | parser.add_argument("-s", metavar="surname", required=True, help="Surname.") 165 | parser.add_argument("-g", metavar="gender", choices=('F', 'M'), required=True, help="Gender(F/M).") 166 | parser.add_argument("-y", type=int, choices=range(1901, 2049), metavar="year", required=True, 167 | help="Year of birth date.") 168 | parser.add_argument("-m", type=int, choices=range(1, 13), metavar="month", required=True, 169 | help="Month of birth date.") 170 | parser.add_argument("-d", type=int, choices=range(1, 32), metavar="day", required=True, 171 | help="Day of birth date.") 172 | parser.add_argument("-H", type=int, choices=range(0, 24), metavar="hour", required=True, 173 | help="Hour of birth datetime.") 174 | args = parser.parse_args() 175 | 176 | attr_list = output_wuxing(args.y, args.m, args.d, args.H) 177 | filter_name(args.s, args.g, attr_list) 178 | -------------------------------------------------------------------------------- /db/data.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repoog/ReName/f082bf43322b7396e6cc315adc8dfcd0033083dc/db/data.zip -------------------------------------------------------------------------------- /lib/DB.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | try: 3 | import pymysql 4 | except ImportError: 5 | print("[!_!]ERROR INFO: You have to install pymysql module.") 6 | exit() 7 | 8 | HOST = "localhost" 9 | PORT = 3306 10 | USER = "rename" 11 | PASS = "" 12 | DATABASE = "rename" 13 | 14 | 15 | class DBOP(object): 16 | """ 17 | MySQL operation class for logging command logs and searching logs 18 | """ 19 | def __init__(self): 20 | try: 21 | self.db = pymysql.connect(HOST, USER, PASS, DATABASE, PORT, charset='utf8') 22 | except pymysql.OperationalError as e: 23 | print(e) 24 | exit() 25 | self.cursor = self.db.cursor() 26 | 27 | def __del__(self): 28 | self.db.close() 29 | 30 | def get_wuxing_name(self, wuxing_list): 31 | wuxing_sql = 'SELECT word FROM rn_wuxing WHERE 1 = 2' 32 | for word in wuxing_list: 33 | wuxing_sql += ' OR type="%s"' % word 34 | name_sql = 'SELECT a.wid, a.word FROM rn_word_unique a ' \ 35 | 'WHERE EXISTS (SELECT b.word FROM (%s) b WHERE SUBSTR(a.word, 1, 1) = b.word) ' \ 36 | 'AND EXISTS (SELECT b.word FROM (%s) b WHERE SUBSTR(a.word, 2, 1) = b.word)' % \ 37 | (wuxing_sql, wuxing_sql) 38 | self.cursor.execute(name_sql) 39 | name_set = self.cursor.fetchall() 40 | return name_set 41 | 42 | def match_name_word(self, name): 43 | name_word_sql = 'SELECT COUNT(1) FROM rn_name_word WHERE word IN ("%s", "%s")' % (name[0], name[1]) 44 | self.cursor.execute(name_word_sql) 45 | match_count = self.cursor.fetchone() 46 | return True if match_count[0] == 2 else False 47 | 48 | def get_name_source(self, wid): 49 | source_sql = 'SELECT decade, poet, poem, content FROM rn_poem_content WHERE wid=%s' 50 | self.cursor.execute(source_sql, (wid)) 51 | source = self.cursor.fetchall() 52 | return source[0] 53 | 54 | 55 | if __name__ == "__main__": 56 | pass 57 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repoog/ReName/f082bf43322b7396e6cc315adc8dfcd0033083dc/lib/__init__.py -------------------------------------------------------------------------------- /lib/boxcalendar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright 2014 ccdjh 5 | 6 | import datetime 7 | 8 | CHINESE_1990_2100 = [ 9 | 51397716,54792469,205819985,55641108,55656721,206770449,51450948,54608977,207688017,51397716, 10 | 219177285,54792273,55641105,222610449,54858000,55645252,220483908,54595909,205589781,51396885, 11 | 54792261,219451461,51659793,51663120,219366673,50611476,54595861,207684693,51396885,206594324, 12 | 55644228,55854097,206685249,51463249,50611476,218895444,54592596,222366801,55591185,55644228, 13 | 222638148,54858001,51450948,219353413,50598225,54592593,224461893,54804753,219433233,51662916, 14 | 54858001,205833489,51401028,54792517,206311701,51446853,219219524,55853329,51659844,219243588, 15 | 54805777,51397908,219300948,54792469,51446804,223937556,55656721,205854993,51450948,54596689, 16 | 205623633,51397713,54792273,222695505,55641105,222578193,54858000,54858820,218394948,54595909, 17 | 51396933,219300117,54792261,219418725,51659793,51663120,219243792,54805780,54595861,205620309, 18 | 51396885,51646533,207163460,55854097,206640657,51463248,54805780,218403921,54592596,55591188, 19 | 222707985,55644228,55657489,207950097,51450948,219224389,50598225,54592593,222397509,54804753, 20 | 54857796,219563076,54808849,205800849,51397956,54792517,205795605,51446853,54804741,206979345, 21 | 51659844,54808849,207701265,51397908,219178068,54792276,55641108,223446036,55644421,51463236, 22 | 207164484,54596689,205590873,51397713,54792273,222572613,55641105,55644420,222662928,54858052, 23 | 51450961,207688005,51396933,219171093,54792261,54805521,219464721,51663108,54808900,206325012, 24 | 54592789,205588053,51396885,51646533,206647364,55854097,51659844,219354192,54805588,54592596, 25 | 222889044,55591188,222578961,55644228,55657489,205885713,51450948,54793297,205918545,51446865, 26 | 219219525,54804753,54857796,219440196,54808849,51450180,219301188,54792517,51446853,219743253, 27 | 51659013,206838021,51659844,54808849,205636881,51397908,54792469,205918292,55640340,223413780, 28 | 55644420,55657540,206648388,51450961,51397716,219300177,54789201,55640337,224723985,55644420, 29 | ] 30 | 31 | CHANGE_1990_2100_24 = [ 32 | 485536035763181,489951330300910,491395512218606,561397770413033,485536035763182,489951263192046, 33 | 491395512218606,561397770347497,485536035763181,489951263192046,491395512218606,561397770413033, 34 | 467943782609901,485536036811758,491119561356270,491029026238425,467943581279209,485536036811757, 35 | 491119561356270,491029026238425,467939286311913,485536036811757,489951330251758,491029026238425, 36 | 467939286311913,485536035763181,489951330300910,491029009460889,467939282052073,485536035763181, 37 | 489951330300910,491029026238105,467939282052073,485536035763181,489951263192046,491029009460889, 38 | 467939282052073,485536035763181,489951263192046,491029009460889,467939282052073,485536035763181, 39 | 489951263192046,491027935719065,467939282055129,467943849714669,485536036811758,490753057549977, 40 | 397570537877465,467939286246381,485536036811758,490753057549977,397570537877465,467939286311913, 41 | 485536035763181,490684338073241,397570537877465,467939282052073,485536035763181,489584826429081, 42 | 397570521099929,467939282052073,485536035763181,489584826429081,397570521099929,467939282052073, 43 | 485536035763181,489584759320217,397570521099929,467939282052073,485536035765997,489584759320217, 44 | 397569447358105,467939282052073,485536035759085,489567579451033,397569447095961,467939282055145, 45 | 485535767323629,489567579451033,397569447095961,467939282055129,467939286311917,485169531891353, 46 | 397294569189017,397570537877465,467939282117609,485169531891352,397225849695897,397570521100249, 47 | 467939282052073,485169532939928,396126338068121,397570521099929,467939282052073,485169531891352, 48 | 396126270959257,397570521099929,467939282052073,485169531891352,396126270959257,397570521099929, 49 | 467939282052073,485169531891352,396126270959257,397569447095961,467939282052073,485169531887256, 50 | 396109091090073,397569447095961,467939282055145,485169263451800,396109090041497,397569447095961, 51 | 467939282055129,467572782440088,391711043530393,397294569189017,397570521100249,467572778180248, 52 | 391711043530392,397225849695897,397570521100249,467572778180244,391711043530392,396126270959257, 53 | 397570521099929,467572778180244,391711043530392,396126270959257,397570521099929,467572778180244, 54 | 391711043530392,396126270959257,397569447095961,467572778180244,391711043530392,396126270959257, 55 | 397569447095961,466473266552468,391710775090840,396109091090073,397569447095961,467572778179220, 56 | 391706480123544,396109090041497,397569447095961,467572761401988,374114289819288,391711043530393, 57 | 397225849695897,379611831179908,374114289819288,391711043530393,397208602717849,397204017224324, 58 | 374114289819284,391711043530392,397225782587033,397204017224004,374114289819284,391711043530392, 59 | 396126270959257,397204017224004,374114289819284,391711043530392,396126270959257,397202943220036, 60 | 374114289819284,391710775029400,396126270959257,397202943220036,374114289818260,391710775090840, 61 | 396109090041497,397202943220036,374114289818260,391706475929240,396109090041497,397202943220036, 62 | 375213784668804,391706475863704,391711043530393,397134223726916,303745528601220,374114289819288, 63 | 391711043530393,397134156618052,303745528846724,374114289819284,391711043530392,397134156618052, 64 | 303745528863044,374114289819284,391711043530392,396034644990276,303745528600900,374114289819284, 65 | 391711043530392,396126270959257, 66 | ] 67 | 68 | CHINESE_60= [ 69 | '0000','0101','0202','0303','0404','0505','0606','0707','0808','0909','0010','0111', 70 | '0200','0301','0402','0503','0604','0705','0806','0907','0008','0109','0210','0311', 71 | '0400','0501','0602','0703','0804','0905','0006','0107','0208','0309','0410','0511', 72 | '0600','0701','0802','0903','0004','0105','0206','0307','0408','0509','0610','0711', 73 | '0800','0901','0002','0103','0204','0305','0406','0507','0608','0709','0810','0911', 74 | ] 75 | 76 | CHINESE_24_1 = [ 77 | u"小寒",u"大寒",u"立春",u"雨水",u"驚蟄",u"春分",u"清明",u"穀雨",u"立夏",u"小滿",u"芒種",u"夏至", 78 | u"小暑",u"大暑",u"立秋",u"處暑",u"白露",u"秋分",u"寒露",u"霜降",u"立冬",u"小雪",u"大雪",u"冬至", 79 | ] 80 | 81 | CHINESE_10_1 = [u"甲",u"乙",u"丙",u"丁",u"戊",u"己",u"庚",u"辛",u"壬",u"癸",] 82 | CHINESE_12_1 = [u"子",u"丑",u"寅",u"卯",u"辰",u"巳",u"午",u"未",u"申",u"酉",u"戌",u"亥",] 83 | CHINESE_12_2 = [u"鼠",u"牛",u"虎",u"兔",u"龍",u"蛇",u"馬",u"羊",u"猴",u"雞",u"狗",u"豬",] 84 | 85 | def lunarday(english_year,english_month,english_day): 86 | #旧历的计算 87 | chinese_years_days = helper_days_list() 88 | english_days = datetime.date(english_year,english_month,english_day) - datetime.date(1901,1,1) 89 | english_days = english_days.days #获取输入日期的天数 90 | if english_days <50: 91 | d49 = day_49(english_year,english_month,english_day) 92 | return d49 93 | chinese_year_list = helper_year_data_find(english_days,chinese_years_days) #获得年位置 [33271, 91, 1992, 16] 94 | 95 | change_dict = { '00':29, '01':30, '10':29,'11':30,} 96 | a = bin(CHINESE_1990_2100[chinese_year_list[1]]) 97 | b = [ a[i:i+2] for i in range(0, len(a),2)][2:] #二进制列表 98 | c = [ change_dict[x] if x in change_dict else x for x in b]#十进制列表 99 | 100 | d = [ sum(c[0:i]) for i in range(len(c))] #月份的天数 101 | chinese_month_list = helper_month_data_find(chinese_year_list[3] ,d) #获得月位置 [0, 0, 1, 17] 102 | chinese_month_list_2 = chinese_month_list[2] 103 | b_len= len(b) 104 | if b_len == 13: 105 | r = [ (i,b.index(i)) for i in b if i=='10' or i=='11'][0] 106 | chinese_month_list_2 = chinese_month_list_2-1 if chinese_month_list_2 > r[1] else chinese_month_list_2 107 | 108 | #天干地支的计算 109 | chinese_years_days_60 = helper_days_60_list() 110 | chinese_year_list = helper_year_60_data_find(english_days,chinese_years_days_60) #获得年干支位置[1130, 3, 1904, 60] 111 | year_60_list = CHINESE_60 + CHINESE_60 +CHINESE_60 + CHINESE_60 + CHINESE_60 112 | year_60_list = year_60_list [37:37+200] #生成年干支列表 113 | 114 | e = bin(CHANGE_1990_2100_24[chinese_year_list[1]])#解析24气节的数据 115 | e = e[3:] 116 | f = [ e[i:i+2] for i in range(0, len(e),2)]#去除保留数值 117 | g = [ f[i] for i in range(2,len(f),2)] 118 | a1= { '00':'2', '01':'3', '10':'4','11':'5',} 119 | a2= { '00':'4', '01':'5', '10':'6','11':'7',} 120 | a3= { '00':'9', '01':'6', '10':'7','11':'8',} 121 | g_list = [a1[g[0]],a2[g[1]],a2[g[2]],a2[g[3]],a2[g[4]],a3[g[5]],a3[g[6]],a3[g[7]],a3[g[8]],a3[g[9]],a3[g[10]],]#转换为10进制的列表 122 | 123 | e2 = bin(CHANGE_1990_2100_24[chinese_year_list[1]+1])#获取向前一年的u"小寒",u"大寒" 124 | e2 = e2[3:] 125 | f2 = [ e2[i:i+2] for i in range(0, len(e2),2)] 126 | g2 = [ f2[i] for i in range(0,len(f2),2)] 127 | g_list = g_list + [a2[g2[0]]] #生成完整的10进制列表 128 | 129 | g_list_new = [] 130 | for v in range(11): 131 | v_day = datetime.date(chinese_year_list[2],2+v,int(g_list[v])) - datetime.date(chinese_year_list[2],2,int(g_list[0])) 132 | g_list_new.append(v_day.days ) 133 | v_day_2 = datetime.date(chinese_year_list[2]+1,1,int(g_list[11])) - datetime.date(chinese_year_list[2],2,int(g_list[0])) 134 | g_list_new.append(v_day_2.days) #生成月干支天数,数据列表 135 | chinese_month_days_60 = helper_month_60_data_find(chinese_year_list[3],g_list_new)#获得月干支位置[60, 2, 3, 1] 136 | 137 | year_value_key = int(year_60_list[chinese_year_list[1]][0:2]) #年干 138 | year_value = year_value_key if year_value_key <= 4 else year_value_key-5 #通过年干支定位月干支列表 139 | v1 = CHINESE_10_1 + CHINESE_10_1 + CHINESE_10_1 140 | month_value = 2 +(year_value*2)#获取开始位置的公式 141 | v2 = v1[month_value:month_value+12] #生成月干 142 | v3 = CHINESE_12_1[2:] + CHINESE_12_1[0:2]#生成月支,因为一月为u"寅" 143 | 144 | v4 = datetime.date(english_year,english_month,english_day) - datetime.date(1901,2,15) #日干支 145 | v5 = v4.days%60 146 | f1 = str(english_year) + '-' +str(english_month) + '-' +str(english_day) 147 | f2 = str(chinese_year_list[2]) + '-' + str(chinese_month_list_2) + '-' + str(chinese_month_list[3]) 148 | f3 = CHINESE_10_1[int(year_60_list[chinese_year_list[1]][0:2])]+CHINESE_12_1[int(year_60_list[chinese_year_list[1]][2:4])] + '-' + v2[chinese_month_days_60[1]]+v3[chinese_month_days_60[1]] + '-' + CHINESE_10_1[int(CHINESE_60[v5][0:2])]+CHINESE_12_1[int(CHINESE_60[v5][2:4])] 149 | f4 = CHINESE_12_2[int(year_60_list[chinese_year_list[1]][2:4])] 150 | 151 | return [f1,f2,f3,f4] 152 | 153 | def helper_days_list(): 154 | chinese_years_data =49 155 | chinese_years_list = [49] 156 | change_dict = { '00':29, '01':30, '10':29,'11':30,} 157 | 158 | for i in CHINESE_1990_2100: 159 | a = bin(i) 160 | b = [ a[i:i+2] for i in range(0, len(a),2)][2:] #转为二进制的列表 161 | c = sum([ int(change_dict[x]) if x in change_dict else int(x) for x in b]) #转为十进制的列表 162 | chinese_years_data = chinese_years_data + c #得出年初的天数 163 | chinese_years_list.append(chinese_years_data) #添加进列表 164 | return chinese_years_list #返回列表 165 | 166 | def helper_days_60_list(): 167 | chinese_years_data = 1901 168 | chinese_years_list = [] 169 | change_dict = { '00':'2', '01':'3', '10':'4','11':'5',} 170 | 171 | for t in range(len(CHANGE_1990_2100_24)): 172 | a = bin(CHANGE_1990_2100_24[t]) 173 | a = a[3:] 174 | b = [ a[i:i+2] for i in range(0, len(a),2)][2]#转为二进制的列表 175 | c = int(change_dict[b]) #立春的天数 176 | english_days = datetime.date(chinese_years_data+t,2,c) - datetime.date(1901,1,1) 177 | chinese_years_list.append(english_days.days) #添加进列表 178 | 179 | return chinese_years_list #返回列表 180 | 181 | def helper_month_60_data_find(value,li): 182 | chinese_month_data_find = [ (i,li.index(i)) for i in li if i <= value ][-1] 183 | return [chinese_month_data_find[0],chinese_month_data_find[1],1+ chinese_month_data_find[1],value-chinese_month_data_find[0]+1] 184 | 185 | def helper_year_60_data_find(value,li): 186 | chinese_year_data_find = [ (i,li.index(i)) for i in li if i <= value ][-1] 187 | return [chinese_year_data_find [0],chinese_year_data_find [1],1901+chinese_year_data_find [1],value-chinese_year_data_find[0]] 188 | 189 | def helper_month_data_find(value,li): 190 | chinese_month_data_find = [ (i,li.index(i)) for i in li if i <= value ][-1] 191 | return [chinese_month_data_find[0],chinese_month_data_find[1],1+ chinese_month_data_find[1],value-chinese_month_data_find[0]+1] 192 | 193 | def helper_year_data_find(value,li): 194 | chinese_year_data_find = [ (i,li.index(i)) for i in li if i <= value ][-1] 195 | return [chinese_year_data_find [0],chinese_year_data_find [1],1901+chinese_year_data_find [1],value-chinese_year_data_find[0]] 196 | 197 | def day_49(english_year,english_month,english_day): 198 | english_days = datetime.date(english_year,english_month,english_day) - datetime.date(1901,1,1) 199 | english_days = english_days.days #获取输入日期的天数 200 | chinese_year = '1900' 201 | chinese_month = '12' if english_days>18 else '11' 202 | chinese_day = english_days+11 if chinese_month=='11' else english_days-18 203 | 204 | chinese_year_60 = '0600' if english_days<34 else '0701' #庚子 '辛丑' 205 | chinese_month_60 = u'戊子' if english_days<6 else (u'乙丑' if english_days<34 else u'庚寅' ) 206 | 207 | v4 = datetime.date(english_year,english_month,english_day) - datetime.date(1900,12,17) #日干支 208 | v5 = v4.days%60 209 | 210 | f1 = str(english_year) + '-' +str(english_month) + '-' +str(english_day) 211 | f2 = chinese_year +'-' + chinese_month +'-' + str(chinese_day) 212 | a = CHINESE_10_1[int(chinese_year_60[0:2])]+CHINESE_12_1[int(chinese_year_60[2:4])] 213 | c = CHINESE_10_1[int(CHINESE_60[v5][0:2])]+CHINESE_12_1[int(CHINESE_60[v5][2:4])] 214 | 215 | f3 = a + '-' + chinese_month_60 + '-' + c 216 | f4 = f4 = CHINESE_12_2[int(CHINESE_60[v5][2:4])] 217 | 218 | return [f1,f2,f3,f4] 219 | 220 | 221 | if __name__ == '__main__': 222 | pass 223 | --------------------------------------------------------------------------------