├── tests ├── __init__.py ├── conftest.py ├── regression │ ├── test_horoscope.py │ └── test_astrolabe.py └── data │ ├── horoscope.json │ └── astro.json ├── examples ├── __init__.py ├── daxian.py ├── config.py └── base.py ├── js_test ├── .gitignore ├── package.json ├── config.js └── package-lock.json ├── src └── py_iztro │ ├── core │ ├── __init__.py │ ├── astro.py │ └── models.py │ └── __init__.py ├── Makefile ├── .gitignore ├── CHANGELOG.md ├── .pre-commit-config.yaml ├── .github └── workflows │ └── coverage.yml ├── pyproject.toml └── README.md /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js_test/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/py_iztro/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js_test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "iztro": "^2.5.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pytest 4 | 5 | 6 | @pytest.fixture 7 | def test_data_dir() -> Path: 8 | return Path(__file__).parent / "data" 9 | -------------------------------------------------------------------------------- /src/py_iztro/__init__.py: -------------------------------------------------------------------------------- 1 | from py_iztro.core import models 2 | from py_iztro.core.astro import Astro, AstrolabeModel 3 | 4 | __version__ = "0.1.5" 5 | __all__ = ( 6 | "Astro", 7 | "AstrolabeModel", 8 | "models", 9 | ) 10 | -------------------------------------------------------------------------------- /examples/daxian.py: -------------------------------------------------------------------------------- 1 | from py_iztro import Astro 2 | 3 | 4 | def main(): 5 | astro = Astro() 6 | result = astro.by_solar("2000-8-16", 2, "女") 7 | result = result.horoscope("2025-01-01").model_dump_json(by_alias=True, indent=4) 8 | print(result) 9 | 10 | 11 | if __name__ == "__main__": 12 | main() 13 | -------------------------------------------------------------------------------- /js_test/config.js: -------------------------------------------------------------------------------- 1 | import {astro} from 'iztro'; 2 | 3 | console.log("默认配置: ", astro.getConfig()) 4 | const config = { 5 | 'mutagens': {'庚': ['太阳', '武曲', '天同', '天相']}, 6 | 'brightness': {'贪狼': ['旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺']}, 7 | } 8 | 9 | astro.config(config) 10 | console.log("修改后配置: ", astro.getConfig()) 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: sb spt sp check check_i 2 | 3 | build: 4 | rm -rf ./dist 5 | uv build 6 | 7 | publish_testpypi: 8 | uv run twine upload -r testpypi dist/* 9 | 10 | publish_pypi: 11 | uv run twine upload dist/* 12 | 13 | test: build publish_testpypi 14 | 15 | release: build publish_pypi 16 | 17 | check: 18 | uv run pre-commit run --all-files 19 | 20 | check_i: 21 | uv run pre-commit install 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # python generated files 2 | __pycache__/ 3 | *.py[oc] 4 | build/ 5 | dist/ 6 | wheels/ 7 | *.egg-info 8 | 9 | # venv 10 | .venv 11 | .vscode 12 | .idea 13 | 14 | # rye 15 | .python-version 16 | 17 | # mac 18 | .DS_Store 19 | 20 | # Unit test / coverage reports 21 | htmlcov/ 22 | .tox/ 23 | .nox/ 24 | .coverage 25 | .coverage.* 26 | .cache 27 | nosetests.xml 28 | coverage.xml 29 | *.cover 30 | *.py,cover 31 | .hypothesis/ 32 | .pytest_cache/ 33 | cover/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | 9 | ## [0.1.5] - 2025-05-17 10 | 11 | ### Changed 12 | 13 | - 优化tests/base.py示例 14 | 15 | ### Added 16 | 17 | - 增加astro.by_lunar(...) 农历排盘 18 | - 增加config(...)设置配置方法 19 | - 增加getConfig(...)获取配置方法 20 | - 增加tests/config.py示例 21 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | # bandit 5 | - repo: https://github.com/PyCQA/bandit 6 | rev: 1.7.10 7 | hooks: 8 | - id: bandit 9 | args: [ "-c", "pyproject.toml" ] 10 | additional_dependencies: [ "bandit[toml]" ] 11 | 12 | # ruff 13 | - repo: https://github.com/astral-sh/ruff-pre-commit 14 | rev: 'v0.6.9' 15 | hooks: 16 | - id: ruff 17 | args: [ --fix, --exit-non-zero-on-fix, --show-fixes ] 18 | - id: ruff-format 19 | -------------------------------------------------------------------------------- /examples/config.py: -------------------------------------------------------------------------------- 1 | from py_iztro import Astro 2 | from py_iztro.core.models import ConfigModel 3 | 4 | 5 | def main(): 6 | astro = Astro() 7 | config = astro.get_config() 8 | print(f"默认配置: {config.model_dump_json(indent=4)}") 9 | 10 | config_model = ConfigModel( 11 | mutagens={"庚": ["太阳", "武曲", "天同", "天相"]}, 12 | brightness={"贪狼": ["旺", "旺", "旺", "旺", "旺", "旺", "旺", "旺", "旺", "旺", "旺", "旺"]}, 13 | ) 14 | astro.config(config_model) 15 | config = astro.get_config() 16 | print(f"修改后配置: {config.model_dump_json(indent=4)}") 17 | 18 | 19 | if __name__ == "__main__": 20 | main() 21 | -------------------------------------------------------------------------------- /tests/regression/test_horoscope.py: -------------------------------------------------------------------------------- 1 | import json 2 | from pathlib import Path 3 | 4 | from py_iztro.core.astro import Astro 5 | from py_iztro.core.models import HoroscopeModel 6 | 7 | 8 | def test_horoscope(test_data_dir: Path): 9 | json_path = test_data_dir / "horoscope.json" 10 | with open(json_path, encoding="utf-8") as f: 11 | expected = HoroscopeModel.model_validate(json.load(f)) 12 | 13 | astro = Astro() 14 | astrolabe = astro.by_solar("2000-8-16", 2, "女") 15 | result = astrolabe.horoscope("2025-01-01").model_dump_json(by_alias=True) 16 | assert result == expected.model_dump_json(by_alias=True) 17 | -------------------------------------------------------------------------------- /examples/base.py: -------------------------------------------------------------------------------- 1 | from py_iztro import Astro 2 | 3 | 4 | def main(): 5 | astro = Astro() 6 | 7 | # 通过阳历调用紫薇斗数排盘 8 | result_solar = astro.by_solar("2000-8-16", 2, "女") 9 | result_solar_data = result_solar.model_dump_json(by_alias=True, indent=4) 10 | print(result_solar_data) 11 | 12 | # 通过农历调用紫薇斗数排盘 13 | result_lunar = astro.by_lunar("2000-7-17", 2, "女") 14 | result_lunar_data = result_lunar.model_dump_json(by_alias=True, indent=4) 15 | print(result_lunar_data) 16 | 17 | # 比较阳历和农历的结果是否相同 18 | print(result_solar_data == result_lunar_data) 19 | 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Run tests and upload coverage 2 | 3 | on: 4 | push 5 | 6 | jobs: 7 | test: 8 | name: Run tests and collect coverage 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Set up Python 17 | uses: actions/setup-python@v4 18 | 19 | - name: Install dependencies 20 | run: | 21 | pip install -e . 22 | pip install pytest pytest-cov 23 | 24 | - name: Run tests 25 | run: pytest --cov-branch --cov-report=xml 26 | 27 | - name: Upload results to Codecov 28 | uses: codecov/codecov-action@v5 29 | with: 30 | token: ${{ secrets.CODECOV_TOKEN }} 31 | -------------------------------------------------------------------------------- /tests/regression/test_astrolabe.py: -------------------------------------------------------------------------------- 1 | from functools import cached_property 2 | 3 | from py_iztro import Astro 4 | from py_iztro.core.models import AstrolabeModel 5 | 6 | 7 | class TestAstroGeneration: 8 | GEORGIAN_DATE = "2000-8-16" 9 | LUNISOLAR_DATE = "2000-7-17" 10 | GENDER = "女" 11 | TIME_IDX = 2 12 | astro = Astro() 13 | 14 | @cached_property 15 | def expected_result(self) -> AstrolabeModel: 16 | # just do not want to load the expected result twice 17 | with open("tests/data/astro.json", encoding="utf-8") as f: 18 | return AstrolabeModel.model_validate_json(f.read()) 19 | 20 | def test_astrolabe_from_georgian_calendar(self): 21 | astrolabe = self.astro.by_solar(self.GEORGIAN_DATE, self.TIME_IDX, self.GENDER) 22 | assert astrolabe.model_dump_json(by_alias=True) == self.expected_result.model_dump_json(by_alias=True) 23 | 24 | def test_astrolabe_from_lunisolar_calendar(self): 25 | astrolabe = self.astro.by_lunar(self.LUNISOLAR_DATE, self.TIME_IDX, self.GENDER) 26 | assert astrolabe.model_dump_json(by_alias=True) == self.expected_result.model_dump_json(by_alias=True) 27 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "py-iztro" 3 | version = "0.1.5" 4 | description = "python版iztro紫微排盘工具" 5 | authors = [ 6 | { name = "昊色居士", email = "xhrtxh@gmail.com" } 7 | ] 8 | dependencies = [ 9 | "pythonmonkey==1.1.0", 10 | "pydantic==2.10.6", 11 | ] 12 | readme = "README.md" 13 | requires-python = ">= 3.10" 14 | 15 | [project.urls] 16 | homepage = "https://github.com/x-haose/py-iztro" 17 | repository = "https://github.com/x-haose/py-iztro" 18 | documentation = "https://github.com/x-haose/py-iztro" 19 | 20 | [dependency-groups] 21 | dev = [ 22 | "pre-commit>=4.2.0", 23 | "twine>=6.1.0", 24 | "pytest", 25 | "pytest-cov" 26 | ] 27 | 28 | [build-system] 29 | requires = ["hatchling"] 30 | build-backend = "hatchling.build" 31 | 32 | [tool.hatch.build.targets.wheel] 33 | packages = ["src/py_iztro"] 34 | 35 | [tool.bandit] 36 | skips = [ 37 | "B501", 38 | "B113", 39 | "B101" 40 | ] 41 | 42 | [tool.ruff] 43 | # Exclude a variety of commonly ignored directories. 44 | exclude = [ 45 | ".bzr", 46 | ".direnv", 47 | ".eggs", 48 | ".git", 49 | ".git-rewrite", 50 | ".hg", 51 | ".ipynb_checkpoints", 52 | ".mypy_cache", 53 | ".nox", 54 | ".pants.d", 55 | ".pyenv", 56 | ".pytest_cache", 57 | ".pytype", 58 | ".ruff_cache", 59 | ".svn", 60 | ".tox", 61 | ".venv", 62 | ".vscode", 63 | "__pypackages__", 64 | "_build", 65 | "buck-out", 66 | "build", 67 | "dist", 68 | "node_modules", 69 | "site-packages", 70 | "venv", 71 | ] 72 | 73 | # Same as Black. 74 | line-length = 120 75 | indent-width = 4 76 | 77 | # Assume Python 3.12 78 | target-version = "py312" 79 | 80 | [tool.ruff.lint] 81 | select = [ 82 | # pycodestyle error 83 | "E", 84 | # Pyflakes 85 | "F", 86 | # pycodestyle warnings 87 | "W", 88 | # pyupgrade 89 | "UP", 90 | # flake8-comprehensions 91 | "C", 92 | # flake8-bugbear 93 | "B", 94 | # flake8-simplify 95 | "SIM", 96 | # isort 97 | "I", 98 | ] 99 | ignore = [ 100 | # do not perform function calls in argument defaults 101 | "B008", 102 | # too complex 103 | "C901", 104 | ] 105 | fixable = ["ALL"] 106 | unfixable = [] 107 | 108 | [tool.ruff.lint.per-file-ignores] 109 | "__init__.py" = ["F401"] 110 | 111 | [tool.pytest.ini_options] 112 | testpaths = "tests/" 113 | addopts = "--cov --cov-report html --cov-report term-missing --cov-fail-under 80" 114 | 115 | [tool.coverage] 116 | [tool.coverage.run] 117 | source = ["src"] -------------------------------------------------------------------------------- /js_test/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_test", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "iztro": "^2.5.0" 9 | } 10 | }, 11 | "node_modules/@babel/runtime": { 12 | "version": "7.27.1", 13 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", 14 | "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", 15 | "license": "MIT", 16 | "engines": { 17 | "node": ">=6.9.0" 18 | } 19 | }, 20 | "node_modules/dayjs": { 21 | "version": "1.11.13", 22 | "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", 23 | "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", 24 | "license": "MIT" 25 | }, 26 | "node_modules/i18next": { 27 | "version": "23.16.8", 28 | "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", 29 | "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", 30 | "funding": [ 31 | { 32 | "type": "individual", 33 | "url": "https://locize.com" 34 | }, 35 | { 36 | "type": "individual", 37 | "url": "https://locize.com/i18next.html" 38 | }, 39 | { 40 | "type": "individual", 41 | "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" 42 | } 43 | ], 44 | "license": "MIT", 45 | "dependencies": { 46 | "@babel/runtime": "^7.23.2" 47 | } 48 | }, 49 | "node_modules/iztro": { 50 | "version": "2.5.0", 51 | "resolved": "https://registry.npmjs.org/iztro/-/iztro-2.5.0.tgz", 52 | "integrity": "sha512-+LR4JokjBjMV6AmyluAm3wugBCbrhpC76MqGURPdJccni3MmDPtembPGC3vbwHb5JCscXKQ2e8uolQtmBb4ONw==", 53 | "license": "MIT", 54 | "dependencies": { 55 | "dayjs": "^1.11.10", 56 | "i18next": "^23.5.1", 57 | "lunar-lite": "^0.2.3", 58 | "lunar-typescript": "^1.7.8" 59 | } 60 | }, 61 | "node_modules/lunar-lite": { 62 | "version": "0.2.3", 63 | "resolved": "https://registry.npmjs.org/lunar-lite/-/lunar-lite-0.2.3.tgz", 64 | "integrity": "sha512-sI8BMt3Q9RFvRJSKOdrutxRVc+REVmo709aeUKlAJFOg04+/PS9z/wORDVLJzo+fgBE7cdiIKGbNk1yU6emepg==", 65 | "license": "MIT", 66 | "dependencies": { 67 | "lunar-typescript": "^1.7.5" 68 | } 69 | }, 70 | "node_modules/lunar-typescript": { 71 | "version": "1.8.0", 72 | "resolved": "https://registry.npmjs.org/lunar-typescript/-/lunar-typescript-1.8.0.tgz", 73 | "integrity": "sha512-hz6JtkC30sd1MrdQ9QEPLrJ+ILlRVLZNWDyZUcU3p8VaYOKRqPoICwsrplM6BVAPRwwf360EFe+PukA+i8LmAw==", 74 | "license": "MIT" 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/py_iztro/core/astro.py: -------------------------------------------------------------------------------- 1 | from importlib import resources 2 | 3 | import pythonmonkey as pm # type: ignore 4 | 5 | from py_iztro.core.models import AstrolabeModel, ConfigModel, GenderType, LanguageType, TimeIndexType 6 | 7 | 8 | class Astro: 9 | def __init__(self): 10 | _js_path = resources.files("py_iztro.res") / "iztro-2.5.0.min.js" 11 | _js_obj = pm.require(str(_js_path)) 12 | self._astro = _js_obj.get("astro") 13 | 14 | def by_solar( 15 | self, 16 | solar_date_str: str, 17 | time_index: TimeIndexType, 18 | gender: GenderType, 19 | fix_leap: bool = True, 20 | language: LanguageType = "zh-CN", 21 | ) -> AstrolabeModel: 22 | """ 23 | 通过阳历获取星盘信息 24 | Args: 25 | solar_date_str: 阳历日期【YYYY-M-D】 26 | time_index: 出生时辰序号【0~12】 27 | - 0: 早子时 28 | - 1: 丑时 29 | - 2: 寅时 30 | - 3: 卯时 31 | - 4: 辰时 32 | - 5: 巳时 33 | - 6: 午时 34 | - 7: 未时 35 | - 8: 申时 36 | - 9: 酉时 37 | - 10: 戌时 38 | - 11: 亥时 39 | - 12: 晚子时 40 | gender: 性别【男|女】 41 | fix_leap: 是否调整闰月情况【默认 true】,假如调整闰月,则闰月的前半个月算上个月,后半个月算下个月 42 | language: 输出语言【默认 zh-CN】,支持的语言有:en-US, ja-JP, ko-KR, zh-CN, zh-TW, vi-VN 43 | 44 | Returns: 45 | 星盘信息 46 | """ 47 | 48 | result = self._astro.bySolar(solar_date_str, time_index, gender, fix_leap, language) 49 | data = AstrolabeModel.from_js_astro_obj(result) 50 | return data 51 | 52 | def by_lunar( 53 | self, 54 | lunar_date_str: str, 55 | time_index: TimeIndexType, 56 | gender: GenderType, 57 | fix_leap: bool = True, 58 | language: LanguageType = "zh-CN", 59 | ) -> AstrolabeModel: 60 | """ 61 | 通过农历获取星盘信息 62 | Args: 63 | lunar_date_str: 农历日期【YYYY-M-D】,例如2000年七月十七则传入 2000-7-17 64 | time_index: 出生时辰序号【0~12】 65 | - 0: 早子时 66 | - 1: 丑时 67 | - 2: 寅时 68 | - 3: 卯时 69 | - 4: 辰时 70 | - 5: 巳时 71 | - 6: 午时 72 | - 7: 未时 73 | - 8: 申时 74 | - 9: 酉时 75 | - 10: 戌时 76 | - 11: 亥时 77 | - 12: 晚子时 78 | gender: 性别【男|女】 79 | fix_leap: 是否调整闰月情况【默认 true】,假如调整闰月,则闰月的前半个月算上个月,后半个月算下个月 80 | language: 输出语言【默认 zh-CN】,支持的语言有:en-US, ja-JP, ko-KR, zh-CN, zh-TW, vi-VN 81 | 82 | Returns: 83 | 星盘信息 84 | """ 85 | result = self._astro.byLunar(lunar_date_str, time_index, gender, fix_leap, language) 86 | data = AstrolabeModel.from_js_astro_obj(result) 87 | return data 88 | 89 | def config(self, config: ConfigModel): 90 | """ 91 | 全局配置四化和亮度 92 | Args: 93 | config: 配置数据 94 | 95 | Returns: 96 | 97 | """ 98 | data = config.model_dump(by_alias=True, mode="json") 99 | self._astro.config(data) 100 | 101 | def get_config(self) -> ConfigModel: 102 | """ 103 | 获取当前配置 104 | Returns: 105 | 配置数据 106 | """ 107 | result = self._astro.getConfig() 108 | data = ConfigModel(**result) 109 | data.mutagens = {k: list(v) for k, v in result["mutagens"].items()} 110 | data.brightness = {k: list(v) for k, v in result["brightness"].items()} 111 | return data 112 | -------------------------------------------------------------------------------- /src/py_iztro/core/models.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from typing import Any, Literal 3 | 4 | from pydantic import BaseModel, Field, PrivateAttr 5 | 6 | TimeIndexType = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 7 | GenderType = Literal["男", "女"] 8 | LanguageType = Literal["en-US", "ja-JP", "ko-KR", "zh-CN", "zh-TW", "vi-VN"] 9 | StarType = Literal["major", "soft", "tough", "adjective", "flower", "helper", "lucun", "tianma"] 10 | 11 | 12 | class StarModel(BaseModel): 13 | """ 14 | 紫微斗数星耀模型 15 | """ 16 | 17 | name: str = Field(alias="name", title="星耀名字", description="星耀名字") 18 | type: StarType = Field( 19 | alias="type", 20 | title="星耀类型", 21 | description="星耀类型(主星 | 吉星 | 煞星 | 杂耀 | 桃花星 | 解神 | 禄存 | 天马)", 22 | ) 23 | scope: str = Field(alias="scope", title="作用范围", description="作用范围(本命盘 | 大限盘 | 流年盘)") 24 | brightness: str | None = Field( 25 | alias="brightness", 26 | default=None, 27 | title="星耀亮度", 28 | description="星耀亮度,若没有亮度数据则此字段为`空字符串`或者 `None`", 29 | ) 30 | mutagen: str | None = Field( 31 | alias="mutagen", default=None, title="四化", description="四化,若未产生四化则此字段为 `None`" 32 | ) 33 | 34 | 35 | class DecadalModel(BaseModel): 36 | """ 37 | 大限模型 38 | """ 39 | 40 | range: list[int] = Field(alias="range", title="大限起止年龄 [起始年龄, 截止年龄]") 41 | heavenly_stem: str = Field(alias="heavenlyStem", title="大限天干") 42 | earthly_branch: str = Field(alias="earthlyBranch", title="大限地支") 43 | 44 | 45 | class HoroscopeItemModel(BaseModel): 46 | """ 47 | 运限对象模型 48 | """ 49 | 50 | index: int = Field(alias="index", title="所在宫位的索引") 51 | name: str = Field(alias="name", title="运限名称") 52 | heavenly_stem: str = Field(alias="heavenlyStem", title="该运限天干") 53 | earthly_branch: str = Field(alias="earthlyBranch", title="该运限地支") 54 | palace_names: list[str] = Field(alias="palaceNames", title="该运限的十二宫") 55 | mutagen: list[str] = Field(alias="mutagen", title="四化星") 56 | stars: list[list[StarModel]] | None = Field(alias="stars", default=None, title="流耀") 57 | 58 | 59 | class SoulAndBodyModel(BaseModel): 60 | """ 61 | 命宫、身宫对象模型 62 | """ 63 | 64 | soul_indx: int = Field(alias="soulIndex", title="命宫索引") 65 | body_indx: int = Field(alias="bodyIndex", title="身宫索引") 66 | heavenly_stem_of_soul: str = Field(alias="heavenlyStemOfSoul", title="命宫天干") 67 | earthly_branch_of_soul: str = Field(alias="earthlyBranchOfBody", title="命宫地支") 68 | 69 | 70 | class PalaceModel(BaseModel): 71 | """ 72 | 宫位对象模型 73 | """ 74 | 75 | index: int = Field(alias="index", title="宫位索引") 76 | name: str = Field(alias="name", title="宫位名称") 77 | is_body_palace: bool = Field(alias="isBodyPalace", title="是否身宫") 78 | is_original_palace: bool = Field(alias="isOriginalPalace", title="是否来因宫") 79 | heavenly_stem: str = Field(alias="heavenlyStem", title="宫位天干") 80 | earthly_branch: str = Field(alias="earthlyBranch", title="宫位地支") 81 | major_stars: list[StarModel] = Field(alias="majorStars", title="主星") 82 | minor_stars: list[StarModel] = Field(alias="minorStars", title="辅星") 83 | adjective_stars: list[StarModel] = Field(alias="adjectiveStars", title="杂耀") 84 | changsheng12: str = Field(alias="changsheng12", title="长生12神") 85 | boshi12: str = Field(alias="boshi12", title="博士12神") 86 | jiangqian12: str = Field(alias="jiangqian12", title="流年将前12神") 87 | suiqian12: str = Field(alias="suiqian12", title="流年岁前12神") 88 | decadal: DecadalModel = Field(alias="decadal", title="大限") 89 | ages: list[int] = Field(alias="ages", title="小限") 90 | 91 | 92 | class SurroundedPalacesModel(BaseModel): 93 | """ 94 | 三方四正宫位模型 95 | """ 96 | 97 | target: PalaceModel = Field(alias="target", title="目标宫位, 本宫") 98 | opposite: PalaceModel = Field(alias="opposite", title="对宫") 99 | wealth: PalaceModel = Field(alias="wealth", title="三方位(财帛位)") 100 | career: PalaceModel = Field(alias="career", title="三方位(官禄位)") 101 | 102 | 103 | class HoroscopeItemAgeModel(HoroscopeItemModel): 104 | """ 105 | 运限小限模型 106 | """ 107 | 108 | nominal_age: int = Field(alias="nominalAge", title="虚岁") 109 | 110 | 111 | class HoroscopeItemYearlyModel(HoroscopeItemModel): 112 | """ 113 | 运限流年模型 114 | """ 115 | 116 | class YearlyDecStarModel(BaseModel): 117 | jiangqian12: list[str] = Field(alias="jiangqian12", title="流年将前12神") 118 | suiqian12: list[str] = Field(alias="suiqian12", title="流年岁前12神") 119 | 120 | yearly_dec_star: YearlyDecStarModel = Field(alias="yearlyDecStar", title="流年12神") 121 | 122 | 123 | class HoroscopeModel(BaseModel): 124 | """ 125 | 运限模型 126 | """ 127 | 128 | lunar_date: str = Field(alias="lunarDate", title="农历日期") 129 | solar_date: str = Field(alias="solarDate", title="阳历日期") 130 | decadal: HoroscopeItemModel = Field(alias="decadal", title="大限") 131 | age: HoroscopeItemAgeModel = Field(alias="age", title="小限") 132 | yearly: HoroscopeItemYearlyModel = Field(alias="yearly", title="流年") 133 | monthly: HoroscopeItemModel = Field(alias="monthly", title="流月") 134 | daily: HoroscopeItemModel = Field(alias="daily", title="流日") 135 | hourly: HoroscopeItemModel = Field(alias="hourly", title="流时") 136 | 137 | 138 | class AstrolabeModel(BaseModel): 139 | """ 140 | 星盘模型 141 | """ 142 | 143 | gender: str = Field(alias="gender", title="性别") 144 | solar_date: str = Field(alias="solarDate", title="阳历日期") 145 | lunar_date: str = Field(alias="lunarDate", title="农历日期") 146 | chinese_date: str = Field(alias="chineseDate", title="干支纪年日期") 147 | time: str = Field(alias="time", title="时辰") 148 | time_range: str = Field(alias="timeRange", title="时辰对应的时间段") 149 | sign: str = Field(alias="sign", title="星座") 150 | zodiac: str = Field(alias="zodiac", title="生肖") 151 | earthly_branch_of_soul_palace: str = Field(alias="earthlyBranchOfSoulPalace", title="命宫地支") 152 | earthly_branch_of_body_palace: str = Field(alias="earthlyBranchOfBodyPalace", title="身宫地支") 153 | soul: str = Field(alias="soul", title="命主") 154 | body: str = Field(alias="body", title="身主") 155 | five_elements_class: str = Field(alias="fiveElementsClass", title="五行局") 156 | palaces: list[PalaceModel] = Field(alias="palaces", title="十二宫数据") 157 | 158 | _js_astro_obj: Any = PrivateAttr() 159 | 160 | def horoscope(self, date: str | None = None, time_index: TimeIndexType | None = None) -> HoroscopeModel: 161 | """ 162 | 获取运限数据 163 | 164 | Args: 165 | date: 阳历日期【可选】,默认为调用时的日期 166 | time_index: 时辰索引【可选】,默认会自动读取当前时间的时辰 0-12 167 | 168 | Returns: 169 | 170 | """ 171 | result = self._js_astro_obj.horoscope(date, time_index) 172 | 173 | def _get_horoscope_item_dict( 174 | _data: dict[str, str | list[str]], 175 | ) -> dict[str, str | float | list[str] | list[list[StarModel]]]: 176 | _new_data: dict[str, Any] = dict( 177 | **_data, 178 | palaceNames=list(_data["palaceNames"]), 179 | mutagen=list(_data["mutagen"]), 180 | stars=[[StarModel(**star) for star in stars] for stars in _data.stars or []], # type: ignore 181 | ) 182 | if _data["yearlyDecStar"]: 183 | _new_data["yearlyDecStar"] = HoroscopeItemYearlyModel.YearlyDecStarModel( 184 | jiangqian12=list(_data["yearlyDecStar"]["jiangqian12"]), # type: ignore 185 | suiqian12=list(_data["yearlyDecStar"]["suiqian12"]), # type: ignore 186 | ) 187 | return _new_data 188 | 189 | return HoroscopeModel( 190 | lunarDate=result.lunarDate, 191 | solarDate=result.solarDate, 192 | decadal=HoroscopeItemModel.model_validate(_get_horoscope_item_dict(result.decadal)), 193 | age=HoroscopeItemAgeModel.model_validate(_get_horoscope_item_dict(result.age)), 194 | yearly=HoroscopeItemYearlyModel.model_validate(_get_horoscope_item_dict(result.yearly)), 195 | monthly=HoroscopeItemModel.model_validate(_get_horoscope_item_dict(result.monthly)), 196 | daily=HoroscopeItemModel.model_validate(_get_horoscope_item_dict(result.daily)), 197 | hourly=HoroscopeItemModel.model_validate(_get_horoscope_item_dict(result.hourly)), 198 | ) 199 | 200 | @classmethod 201 | def from_js_astro_obj(cls, js_astro_obj: Any) -> "AstrolabeModel": 202 | astro = cls(**js_astro_obj) 203 | for palace in js_astro_obj.palaces: 204 | p = PalaceModel(**dict(palace, decadal=DecadalModel(**palace.decadal))) 205 | p.decadal.range = list(map(int, palace.decadal.range)) 206 | p.major_stars = [StarModel(**major_star) for major_star in palace.majorStars] 207 | p.minor_stars = [StarModel(**minor_star) for minor_star in palace.minorStars] 208 | p.adjective_stars = [StarModel(**adjective_star) for adjective_star in palace.adjectiveStars] 209 | p.ages = list(map(int, palace.ages)) 210 | astro.palaces.append(p) 211 | astro._js_astro_obj = js_astro_obj 212 | return astro 213 | 214 | 215 | class YearDivideEnum(str, Enum): 216 | """ 217 | 年分割点枚举 218 | """ 219 | 220 | # 正月初一分界 221 | NORMAL = "normal" 222 | # 立春分界 223 | EXACT = "exact" 224 | 225 | 226 | class AgeDivideEnum(str, Enum): 227 | """ 228 | 小限分割点枚举 229 | """ 230 | 231 | # 只考虑年份,不考虑生日 232 | NORMAL = "normal" 233 | # 以生日为分界点 234 | BIRTHDAY = "birthday" 235 | 236 | 237 | class AlgorithmEnum(str, Enum): 238 | """ 239 | 紫薇派别 240 | """ 241 | 242 | # 以《紫微斗数全书》为基础安星 243 | DEFAULT = "default" 244 | # 以中州派安星法为基础安星 245 | ZHONGZHOU = "zhongzhou" 246 | 247 | 248 | class ConfigModel(BaseModel): 249 | """ 250 | 配置模型 251 | """ 252 | 253 | # 四化表配置。如: 254 | # { 庚: ['太阳', '武曲', '天同', '天相'] } 255 | mutagens: dict[str, list[str]] | None = Field(default_factory=dict, title="四化表的配置") 256 | # 星耀在十二宫的亮度配置 如 257 | # { 贪狼: ['旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺'] } 258 | brightness: dict[str, list[str]] | None = Field(default_factory=dict, title="星耀在十二宫的亮度") 259 | # 年分割点配置 260 | # - YearDivideEnum.NORMA: 正月初一分界 261 | # - YearDivideEnum.EXACT: 立春分界 262 | year_divide: YearDivideEnum | None = Field(default=YearDivideEnum.NORMAL, title="年分割点", alias="yearDivide") 263 | # 小限分割点 264 | # - AgeDivideEnum.NORMA: 只考虑年份,不考虑生日 265 | # - AgeDivideEnum.BIRTHDAY: 以生日为分界点 266 | age_divide: AgeDivideEnum | None = Field(default=AgeDivideEnum.NORMAL, title="小限分割点", alias="ageDivide") 267 | # 运限分割点配置 268 | # - YearDivideEnum.NORMA: 正月初一分界 269 | # - YearDivideEnum.EXACT: 立春分界 270 | horoscope_divide: YearDivideEnum | None = Field( 271 | default=YearDivideEnum.NORMAL, title="xx分割点", alias="horoscopeDivide" 272 | ) 273 | # 安星方法 274 | # - AlgorithmEnum.DEFAULT: 以《紫微斗数全书》为基础安星 275 | # - AlgorithmEnum.ZHONGZHOU: 以中州派安星法为基础安星 276 | algorithm: AlgorithmEnum | None = Field(default=AlgorithmEnum.DEFAULT, title="紫微派别") 277 | -------------------------------------------------------------------------------- /tests/data/horoscope.json: -------------------------------------------------------------------------------- 1 | { 2 | "lunarDate": "二〇二四年腊月初二", 3 | "solarDate": "2025-1-1", 4 | "decadal": { 5 | "index": 2, 6 | "name": "大限", 7 | "heavenlyStem": "庚", 8 | "earthlyBranch": "辰", 9 | "palaceNames": [ 10 | "夫妻", 11 | "兄弟", 12 | "命宫", 13 | "父母", 14 | "福德", 15 | "田宅", 16 | "官禄", 17 | "仆役", 18 | "迁移", 19 | "疾厄", 20 | "财帛", 21 | "子女" 22 | ], 23 | "mutagen": [ 24 | "太阳", 25 | "武曲", 26 | "太阴", 27 | "天同" 28 | ], 29 | "stars": [ 30 | [ 31 | { 32 | "name": "运马", 33 | "type": "tianma", 34 | "scope": "decadal", 35 | "brightness": null, 36 | "mutagen": null 37 | } 38 | ], 39 | [ 40 | { 41 | "name": "运曲", 42 | "type": "soft", 43 | "scope": "decadal", 44 | "brightness": null, 45 | "mutagen": null 46 | } 47 | ], 48 | [], 49 | [ 50 | { 51 | "name": "运喜", 52 | "type": "flower", 53 | "scope": "decadal", 54 | "brightness": null, 55 | "mutagen": null 56 | } 57 | ], 58 | [], 59 | [ 60 | { 61 | "name": "运钺", 62 | "type": "soft", 63 | "scope": "decadal", 64 | "brightness": null, 65 | "mutagen": null 66 | }, 67 | { 68 | "name": "运陀", 69 | "type": "tough", 70 | "scope": "decadal", 71 | "brightness": null, 72 | "mutagen": null 73 | } 74 | ], 75 | [ 76 | { 77 | "name": "运禄", 78 | "type": "lucun", 79 | "scope": "decadal", 80 | "brightness": null, 81 | "mutagen": null 82 | } 83 | ], 84 | [ 85 | { 86 | "name": "运羊", 87 | "type": "tough", 88 | "scope": "decadal", 89 | "brightness": null, 90 | "mutagen": null 91 | } 92 | ], 93 | [], 94 | [ 95 | { 96 | "name": "运昌", 97 | "type": "soft", 98 | "scope": "decadal", 99 | "brightness": null, 100 | "mutagen": null 101 | }, 102 | { 103 | "name": "运鸾", 104 | "type": "flower", 105 | "scope": "decadal", 106 | "brightness": null, 107 | "mutagen": null 108 | } 109 | ], 110 | [], 111 | [ 112 | { 113 | "name": "运魁", 114 | "type": "soft", 115 | "scope": "decadal", 116 | "brightness": null, 117 | "mutagen": null 118 | } 119 | ] 120 | ] 121 | }, 122 | "age": { 123 | "index": 8, 124 | "name": "小限", 125 | "heavenlyStem": "丙", 126 | "earthlyBranch": "戌", 127 | "palaceNames": [ 128 | "官禄", 129 | "仆役", 130 | "迁移", 131 | "疾厄", 132 | "财帛", 133 | "子女", 134 | "夫妻", 135 | "兄弟", 136 | "命宫", 137 | "父母", 138 | "福德", 139 | "田宅" 140 | ], 141 | "mutagen": [ 142 | "天同", 143 | "天机", 144 | "文昌", 145 | "廉贞" 146 | ], 147 | "stars": [], 148 | "nominalAge": 25 149 | }, 150 | "yearly": { 151 | "index": 2, 152 | "name": "流年", 153 | "heavenlyStem": "甲", 154 | "earthlyBranch": "辰", 155 | "palaceNames": [ 156 | "夫妻", 157 | "兄弟", 158 | "命宫", 159 | "父母", 160 | "福德", 161 | "田宅", 162 | "官禄", 163 | "仆役", 164 | "迁移", 165 | "疾厄", 166 | "财帛", 167 | "子女" 168 | ], 169 | "mutagen": [ 170 | "廉贞", 171 | "破军", 172 | "武曲", 173 | "太阳" 174 | ], 175 | "stars": [ 176 | [ 177 | { 178 | "name": "流禄", 179 | "type": "lucun", 180 | "scope": "yearly", 181 | "brightness": null, 182 | "mutagen": null 183 | }, 184 | { 185 | "name": "流马", 186 | "type": "tianma", 187 | "scope": "yearly", 188 | "brightness": null, 189 | "mutagen": null 190 | } 191 | ], 192 | [ 193 | { 194 | "name": "流羊", 195 | "type": "tough", 196 | "scope": "yearly", 197 | "brightness": null, 198 | "mutagen": null 199 | } 200 | ], 201 | [], 202 | [ 203 | { 204 | "name": "流昌", 205 | "type": "soft", 206 | "scope": "yearly", 207 | "brightness": null, 208 | "mutagen": null 209 | }, 210 | { 211 | "name": "流喜", 212 | "type": "flower", 213 | "scope": "yearly", 214 | "brightness": null, 215 | "mutagen": null 216 | } 217 | ], 218 | [ 219 | { 220 | "name": "年解", 221 | "type": "helper", 222 | "scope": "yearly", 223 | "brightness": null, 224 | "mutagen": null 225 | } 226 | ], 227 | [ 228 | { 229 | "name": "流钺", 230 | "type": "soft", 231 | "scope": "yearly", 232 | "brightness": null, 233 | "mutagen": null 234 | } 235 | ], 236 | [], 237 | [ 238 | { 239 | "name": "流曲", 240 | "type": "soft", 241 | "scope": "yearly", 242 | "brightness": null, 243 | "mutagen": null 244 | } 245 | ], 246 | [], 247 | [ 248 | { 249 | "name": "流鸾", 250 | "type": "flower", 251 | "scope": "yearly", 252 | "brightness": null, 253 | "mutagen": null 254 | } 255 | ], 256 | [], 257 | [ 258 | { 259 | "name": "流魁", 260 | "type": "soft", 261 | "scope": "yearly", 262 | "brightness": null, 263 | "mutagen": null 264 | }, 265 | { 266 | "name": "流陀", 267 | "type": "tough", 268 | "scope": "yearly", 269 | "brightness": null, 270 | "mutagen": null 271 | } 272 | ] 273 | ], 274 | "yearlyDecStar": { 275 | "jiangqian12": [ 276 | "岁驿", 277 | "息神", 278 | "华盖", 279 | "劫煞", 280 | "灾煞", 281 | "天煞", 282 | "指背", 283 | "咸池", 284 | "月煞", 285 | "亡神", 286 | "将星", 287 | "攀鞍" 288 | ], 289 | "suiqian12": [ 290 | "吊客", 291 | "病符", 292 | "岁建", 293 | "晦气", 294 | "丧门", 295 | "贯索", 296 | "官符", 297 | "小耗", 298 | "大耗", 299 | "龙德", 300 | "白虎", 301 | "天德" 302 | ] 303 | } 304 | }, 305 | "monthly": { 306 | "index": 9, 307 | "name": "流月", 308 | "heavenlyStem": "丙", 309 | "earthlyBranch": "子", 310 | "palaceNames": [ 311 | "田宅", 312 | "官禄", 313 | "仆役", 314 | "迁移", 315 | "疾厄", 316 | "财帛", 317 | "子女", 318 | "夫妻", 319 | "兄弟", 320 | "命宫", 321 | "父母", 322 | "福德" 323 | ], 324 | "mutagen": [ 325 | "天同", 326 | "天机", 327 | "文昌", 328 | "廉贞" 329 | ], 330 | "stars": [ 331 | [ 332 | { 333 | "name": "月马", 334 | "type": "tianma", 335 | "scope": "monthly", 336 | "brightness": null, 337 | "mutagen": null 338 | } 339 | ], 340 | [ 341 | { 342 | "name": "月鸾", 343 | "type": "flower", 344 | "scope": "monthly", 345 | "brightness": null, 346 | "mutagen": null 347 | } 348 | ], 349 | [ 350 | { 351 | "name": "月陀", 352 | "type": "tough", 353 | "scope": "monthly", 354 | "brightness": null, 355 | "mutagen": null 356 | } 357 | ], 358 | [ 359 | { 360 | "name": "月禄", 361 | "type": "lucun", 362 | "scope": "monthly", 363 | "brightness": null, 364 | "mutagen": null 365 | } 366 | ], 367 | [ 368 | { 369 | "name": "月曲", 370 | "type": "soft", 371 | "scope": "monthly", 372 | "brightness": null, 373 | "mutagen": null 374 | }, 375 | { 376 | "name": "月羊", 377 | "type": "tough", 378 | "scope": "monthly", 379 | "brightness": null, 380 | "mutagen": null 381 | } 382 | ], 383 | [], 384 | [ 385 | { 386 | "name": "月昌", 387 | "type": "soft", 388 | "scope": "monthly", 389 | "brightness": null, 390 | "mutagen": null 391 | } 392 | ], 393 | [ 394 | { 395 | "name": "月钺", 396 | "type": "soft", 397 | "scope": "monthly", 398 | "brightness": null, 399 | "mutagen": null 400 | }, 401 | { 402 | "name": "月喜", 403 | "type": "flower", 404 | "scope": "monthly", 405 | "brightness": null, 406 | "mutagen": null 407 | } 408 | ], 409 | [], 410 | [ 411 | { 412 | "name": "月魁", 413 | "type": "soft", 414 | "scope": "monthly", 415 | "brightness": null, 416 | "mutagen": null 417 | } 418 | ], 419 | [], 420 | [] 421 | ] 422 | }, 423 | "daily": { 424 | "index": 10, 425 | "name": "流日", 426 | "heavenlyStem": "庚", 427 | "earthlyBranch": "午", 428 | "palaceNames": [ 429 | "福德", 430 | "田宅", 431 | "官禄", 432 | "仆役", 433 | "迁移", 434 | "疾厄", 435 | "财帛", 436 | "子女", 437 | "夫妻", 438 | "兄弟", 439 | "命宫", 440 | "父母" 441 | ], 442 | "mutagen": [ 443 | "太阳", 444 | "武曲", 445 | "太阴", 446 | "天同" 447 | ], 448 | "stars": [ 449 | [], 450 | [ 451 | { 452 | "name": "日曲", 453 | "type": "soft", 454 | "scope": "daily", 455 | "brightness": null, 456 | "mutagen": null 457 | }, 458 | { 459 | "name": "日喜", 460 | "type": "flower", 461 | "scope": "daily", 462 | "brightness": null, 463 | "mutagen": null 464 | } 465 | ], 466 | [], 467 | [], 468 | [], 469 | [ 470 | { 471 | "name": "日钺", 472 | "type": "soft", 473 | "scope": "daily", 474 | "brightness": null, 475 | "mutagen": null 476 | }, 477 | { 478 | "name": "日陀", 479 | "type": "tough", 480 | "scope": "daily", 481 | "brightness": null, 482 | "mutagen": null 483 | } 484 | ], 485 | [ 486 | { 487 | "name": "日禄", 488 | "type": "lucun", 489 | "scope": "daily", 490 | "brightness": null, 491 | "mutagen": null 492 | }, 493 | { 494 | "name": "日马", 495 | "type": "tianma", 496 | "scope": "daily", 497 | "brightness": null, 498 | "mutagen": null 499 | } 500 | ], 501 | [ 502 | { 503 | "name": "日羊", 504 | "type": "tough", 505 | "scope": "daily", 506 | "brightness": null, 507 | "mutagen": null 508 | }, 509 | { 510 | "name": "日鸾", 511 | "type": "flower", 512 | "scope": "daily", 513 | "brightness": null, 514 | "mutagen": null 515 | } 516 | ], 517 | [], 518 | [ 519 | { 520 | "name": "日昌", 521 | "type": "soft", 522 | "scope": "daily", 523 | "brightness": null, 524 | "mutagen": null 525 | } 526 | ], 527 | [], 528 | [ 529 | { 530 | "name": "日魁", 531 | "type": "soft", 532 | "scope": "daily", 533 | "brightness": null, 534 | "mutagen": null 535 | } 536 | ] 537 | ] 538 | }, 539 | "hourly": { 540 | "index": 10, 541 | "name": "流时", 542 | "heavenlyStem": "丙", 543 | "earthlyBranch": "子", 544 | "palaceNames": [ 545 | "福德", 546 | "田宅", 547 | "官禄", 548 | "仆役", 549 | "迁移", 550 | "疾厄", 551 | "财帛", 552 | "子女", 553 | "夫妻", 554 | "兄弟", 555 | "命宫", 556 | "父母" 557 | ], 558 | "mutagen": [ 559 | "天同", 560 | "天机", 561 | "文昌", 562 | "廉贞" 563 | ], 564 | "stars": [ 565 | [ 566 | { 567 | "name": "时马", 568 | "type": "tianma", 569 | "scope": "hourly", 570 | "brightness": null, 571 | "mutagen": null 572 | } 573 | ], 574 | [ 575 | { 576 | "name": "时鸾", 577 | "type": "flower", 578 | "scope": "hourly", 579 | "brightness": null, 580 | "mutagen": null 581 | } 582 | ], 583 | [ 584 | { 585 | "name": "时陀", 586 | "type": "tough", 587 | "scope": "hourly", 588 | "brightness": null, 589 | "mutagen": null 590 | } 591 | ], 592 | [ 593 | { 594 | "name": "时禄", 595 | "type": "lucun", 596 | "scope": "hourly", 597 | "brightness": null, 598 | "mutagen": null 599 | } 600 | ], 601 | [ 602 | { 603 | "name": "时曲", 604 | "type": "soft", 605 | "scope": "hourly", 606 | "brightness": null, 607 | "mutagen": null 608 | }, 609 | { 610 | "name": "时羊", 611 | "type": "tough", 612 | "scope": "hourly", 613 | "brightness": null, 614 | "mutagen": null 615 | } 616 | ], 617 | [], 618 | [ 619 | { 620 | "name": "时昌", 621 | "type": "soft", 622 | "scope": "hourly", 623 | "brightness": null, 624 | "mutagen": null 625 | } 626 | ], 627 | [ 628 | { 629 | "name": "时钺", 630 | "type": "soft", 631 | "scope": "hourly", 632 | "brightness": null, 633 | "mutagen": null 634 | }, 635 | { 636 | "name": "时喜", 637 | "type": "flower", 638 | "scope": "hourly", 639 | "brightness": null, 640 | "mutagen": null 641 | } 642 | ], 643 | [], 644 | [ 645 | { 646 | "name": "时魁", 647 | "type": "soft", 648 | "scope": "hourly", 649 | "brightness": null, 650 | "mutagen": null 651 | } 652 | ], 653 | [], 654 | [] 655 | ] 656 | } 657 | } -------------------------------------------------------------------------------- /tests/data/astro.json: -------------------------------------------------------------------------------- 1 | { 2 | "gender": "女", 3 | "solarDate": "2000-8-16", 4 | "lunarDate": "二〇〇〇年七月十七", 5 | "chineseDate": "庚辰 甲申 丙午 庚寅", 6 | "time": "寅时", 7 | "timeRange": "03:00~05:00", 8 | "sign": "狮子座", 9 | "zodiac": "龙", 10 | "earthlyBranchOfSoulPalace": "午", 11 | "earthlyBranchOfBodyPalace": "戌", 12 | "soul": "破军", 13 | "body": "文昌", 14 | "fiveElementsClass": "木三局", 15 | "palaces": [ 16 | { 17 | "index": 0, 18 | "name": "财帛", 19 | "isBodyPalace": false, 20 | "isOriginalPalace": false, 21 | "heavenlyStem": "戊", 22 | "earthlyBranch": "寅", 23 | "majorStars": [ 24 | { 25 | "name": "武曲", 26 | "type": "major", 27 | "scope": "origin", 28 | "brightness": "得", 29 | "mutagen": "权" 30 | }, 31 | { 32 | "name": "天相", 33 | "type": "major", 34 | "scope": "origin", 35 | "brightness": "庙", 36 | "mutagen": "" 37 | } 38 | ], 39 | "minorStars": [ 40 | { 41 | "name": "天马", 42 | "type": "tianma", 43 | "scope": "origin", 44 | "brightness": "", 45 | "mutagen": null 46 | } 47 | ], 48 | "adjectiveStars": [ 49 | { 50 | "name": "解神", 51 | "type": "helper", 52 | "scope": "origin", 53 | "brightness": null, 54 | "mutagen": null 55 | }, 56 | { 57 | "name": "三台", 58 | "type": "adjective", 59 | "scope": "origin", 60 | "brightness": null, 61 | "mutagen": null 62 | }, 63 | { 64 | "name": "天寿", 65 | "type": "adjective", 66 | "scope": "origin", 67 | "brightness": null, 68 | "mutagen": null 69 | }, 70 | { 71 | "name": "天巫", 72 | "type": "adjective", 73 | "scope": "origin", 74 | "brightness": null, 75 | "mutagen": null 76 | }, 77 | { 78 | "name": "天厨", 79 | "type": "adjective", 80 | "scope": "origin", 81 | "brightness": null, 82 | "mutagen": null 83 | }, 84 | { 85 | "name": "阴煞", 86 | "type": "adjective", 87 | "scope": "origin", 88 | "brightness": null, 89 | "mutagen": null 90 | }, 91 | { 92 | "name": "天哭", 93 | "type": "adjective", 94 | "scope": "origin", 95 | "brightness": null, 96 | "mutagen": null 97 | } 98 | ], 99 | "changsheng12": "绝", 100 | "boshi12": "飞廉", 101 | "jiangqian12": "岁驿", 102 | "suiqian12": "吊客", 103 | "decadal": { 104 | "range": [ 105 | 43, 106 | 52 107 | ], 108 | "heavenlyStem": "戊", 109 | "earthlyBranch": "寅" 110 | }, 111 | "ages": [ 112 | 9, 113 | 21, 114 | 33, 115 | 45, 116 | 57, 117 | 69, 118 | 81, 119 | 93, 120 | 105, 121 | 117 122 | ] 123 | }, 124 | { 125 | "index": 1, 126 | "name": "子女", 127 | "isBodyPalace": false, 128 | "isOriginalPalace": false, 129 | "heavenlyStem": "己", 130 | "earthlyBranch": "卯", 131 | "majorStars": [ 132 | { 133 | "name": "太阳", 134 | "type": "major", 135 | "scope": "origin", 136 | "brightness": "庙", 137 | "mutagen": "禄" 138 | }, 139 | { 140 | "name": "天梁", 141 | "type": "major", 142 | "scope": "origin", 143 | "brightness": "庙", 144 | "mutagen": "" 145 | } 146 | ], 147 | "minorStars": [], 148 | "adjectiveStars": [ 149 | { 150 | "name": "天刑", 151 | "type": "adjective", 152 | "scope": "origin", 153 | "brightness": null, 154 | "mutagen": null 155 | } 156 | ], 157 | "changsheng12": "墓", 158 | "boshi12": "奏书", 159 | "jiangqian12": "息神", 160 | "suiqian12": "病符", 161 | "decadal": { 162 | "range": [ 163 | 33, 164 | 42 165 | ], 166 | "heavenlyStem": "己", 167 | "earthlyBranch": "卯" 168 | }, 169 | "ages": [ 170 | 8, 171 | 20, 172 | 32, 173 | 44, 174 | 56, 175 | 68, 176 | 80, 177 | 92, 178 | 104, 179 | 116 180 | ] 181 | }, 182 | { 183 | "index": 2, 184 | "name": "夫妻", 185 | "isBodyPalace": false, 186 | "isOriginalPalace": true, 187 | "heavenlyStem": "庚", 188 | "earthlyBranch": "辰", 189 | "majorStars": [ 190 | { 191 | "name": "七杀", 192 | "type": "major", 193 | "scope": "origin", 194 | "brightness": "庙", 195 | "mutagen": "" 196 | } 197 | ], 198 | "minorStars": [ 199 | { 200 | "name": "右弼", 201 | "type": "soft", 202 | "scope": "origin", 203 | "brightness": "", 204 | "mutagen": "" 205 | }, 206 | { 207 | "name": "火星", 208 | "type": "tough", 209 | "scope": "origin", 210 | "brightness": "陷", 211 | "mutagen": null 212 | } 213 | ], 214 | "adjectiveStars": [ 215 | { 216 | "name": "封诰", 217 | "type": "adjective", 218 | "scope": "origin", 219 | "brightness": null, 220 | "mutagen": null 221 | }, 222 | { 223 | "name": "华盖", 224 | "type": "adjective", 225 | "scope": "origin", 226 | "brightness": null, 227 | "mutagen": null 228 | } 229 | ], 230 | "changsheng12": "死", 231 | "boshi12": "将军", 232 | "jiangqian12": "华盖", 233 | "suiqian12": "岁建", 234 | "decadal": { 235 | "range": [ 236 | 23, 237 | 32 238 | ], 239 | "heavenlyStem": "庚", 240 | "earthlyBranch": "辰" 241 | }, 242 | "ages": [ 243 | 7, 244 | 19, 245 | 31, 246 | 43, 247 | 55, 248 | 67, 249 | 79, 250 | 91, 251 | 103, 252 | 115 253 | ] 254 | }, 255 | { 256 | "index": 3, 257 | "name": "兄弟", 258 | "isBodyPalace": false, 259 | "isOriginalPalace": false, 260 | "heavenlyStem": "辛", 261 | "earthlyBranch": "巳", 262 | "majorStars": [ 263 | { 264 | "name": "天机", 265 | "type": "major", 266 | "scope": "origin", 267 | "brightness": "平", 268 | "mutagen": "" 269 | } 270 | ], 271 | "minorStars": [], 272 | "adjectiveStars": [ 273 | { 274 | "name": "天喜", 275 | "type": "flower", 276 | "scope": "origin", 277 | "brightness": null, 278 | "mutagen": null 279 | }, 280 | { 281 | "name": "天空", 282 | "type": "adjective", 283 | "scope": "origin", 284 | "brightness": null, 285 | "mutagen": null 286 | }, 287 | { 288 | "name": "孤辰", 289 | "type": "adjective", 290 | "scope": "origin", 291 | "brightness": null, 292 | "mutagen": null 293 | } 294 | ], 295 | "changsheng12": "病", 296 | "boshi12": "小耗", 297 | "jiangqian12": "劫煞", 298 | "suiqian12": "晦气", 299 | "decadal": { 300 | "range": [ 301 | 13, 302 | 22 303 | ], 304 | "heavenlyStem": "辛", 305 | "earthlyBranch": "巳" 306 | }, 307 | "ages": [ 308 | 6, 309 | 18, 310 | 30, 311 | 42, 312 | 54, 313 | 66, 314 | 78, 315 | 90, 316 | 102, 317 | 114 318 | ] 319 | }, 320 | { 321 | "index": 4, 322 | "name": "命宫", 323 | "isBodyPalace": false, 324 | "isOriginalPalace": false, 325 | "heavenlyStem": "壬", 326 | "earthlyBranch": "午", 327 | "majorStars": [ 328 | { 329 | "name": "紫微", 330 | "type": "major", 331 | "scope": "origin", 332 | "brightness": "庙", 333 | "mutagen": "" 334 | } 335 | ], 336 | "minorStars": [ 337 | { 338 | "name": "文曲", 339 | "type": "soft", 340 | "scope": "origin", 341 | "brightness": "陷", 342 | "mutagen": "" 343 | } 344 | ], 345 | "adjectiveStars": [ 346 | { 347 | "name": "凤阁", 348 | "type": "adjective", 349 | "scope": "origin", 350 | "brightness": null, 351 | "mutagen": null 352 | }, 353 | { 354 | "name": "天福", 355 | "type": "adjective", 356 | "scope": "origin", 357 | "brightness": null, 358 | "mutagen": null 359 | }, 360 | { 361 | "name": "截路", 362 | "type": "adjective", 363 | "scope": "origin", 364 | "brightness": null, 365 | "mutagen": null 366 | }, 367 | { 368 | "name": "蜚廉", 369 | "type": "adjective", 370 | "scope": "origin", 371 | "brightness": null, 372 | "mutagen": null 373 | }, 374 | { 375 | "name": "年解", 376 | "type": "helper", 377 | "scope": "origin", 378 | "brightness": null, 379 | "mutagen": null 380 | } 381 | ], 382 | "changsheng12": "衰", 383 | "boshi12": "青龙", 384 | "jiangqian12": "灾煞", 385 | "suiqian12": "丧门", 386 | "decadal": { 387 | "range": [ 388 | 3, 389 | 12 390 | ], 391 | "heavenlyStem": "壬", 392 | "earthlyBranch": "午" 393 | }, 394 | "ages": [ 395 | 5, 396 | 17, 397 | 29, 398 | 41, 399 | 53, 400 | 65, 401 | 77, 402 | 89, 403 | 101, 404 | 113 405 | ] 406 | }, 407 | { 408 | "index": 5, 409 | "name": "父母", 410 | "isBodyPalace": false, 411 | "isOriginalPalace": false, 412 | "heavenlyStem": "癸", 413 | "earthlyBranch": "未", 414 | "majorStars": [], 415 | "minorStars": [ 416 | { 417 | "name": "天钺", 418 | "type": "soft", 419 | "scope": "origin", 420 | "brightness": "", 421 | "mutagen": null 422 | }, 423 | { 424 | "name": "陀罗", 425 | "type": "tough", 426 | "scope": "origin", 427 | "brightness": "庙", 428 | "mutagen": null 429 | } 430 | ], 431 | "adjectiveStars": [ 432 | { 433 | "name": "天姚", 434 | "type": "flower", 435 | "scope": "origin", 436 | "brightness": null, 437 | "mutagen": null 438 | }, 439 | { 440 | "name": "空亡", 441 | "type": "adjective", 442 | "scope": "origin", 443 | "brightness": null, 444 | "mutagen": null 445 | } 446 | ], 447 | "changsheng12": "帝旺", 448 | "boshi12": "力士", 449 | "jiangqian12": "天煞", 450 | "suiqian12": "贯索", 451 | "decadal": { 452 | "range": [ 453 | 113, 454 | 122 455 | ], 456 | "heavenlyStem": "癸", 457 | "earthlyBranch": "未" 458 | }, 459 | "ages": [ 460 | 4, 461 | 16, 462 | 28, 463 | 40, 464 | 52, 465 | 64, 466 | 76, 467 | 88, 468 | 100, 469 | 112 470 | ] 471 | }, 472 | { 473 | "index": 6, 474 | "name": "福德", 475 | "isBodyPalace": false, 476 | "isOriginalPalace": false, 477 | "heavenlyStem": "甲", 478 | "earthlyBranch": "申", 479 | "majorStars": [ 480 | { 481 | "name": "破军", 482 | "type": "major", 483 | "scope": "origin", 484 | "brightness": "得", 485 | "mutagen": "" 486 | } 487 | ], 488 | "minorStars": [ 489 | { 490 | "name": "文昌", 491 | "type": "soft", 492 | "scope": "origin", 493 | "brightness": "得", 494 | "mutagen": "" 495 | }, 496 | { 497 | "name": "禄存", 498 | "type": "lucun", 499 | "scope": "origin", 500 | "brightness": "", 501 | "mutagen": null 502 | } 503 | ], 504 | "adjectiveStars": [ 505 | { 506 | "name": "龙池", 507 | "type": "adjective", 508 | "scope": "origin", 509 | "brightness": null, 510 | "mutagen": null 511 | }, 512 | { 513 | "name": "台辅", 514 | "type": "adjective", 515 | "scope": "origin", 516 | "brightness": null, 517 | "mutagen": null 518 | }, 519 | { 520 | "name": "旬空", 521 | "type": "adjective", 522 | "scope": "origin", 523 | "brightness": null, 524 | "mutagen": null 525 | } 526 | ], 527 | "changsheng12": "临官", 528 | "boshi12": "博士", 529 | "jiangqian12": "指背", 530 | "suiqian12": "官符", 531 | "decadal": { 532 | "range": [ 533 | 103, 534 | 112 535 | ], 536 | "heavenlyStem": "甲", 537 | "earthlyBranch": "申" 538 | }, 539 | "ages": [ 540 | 3, 541 | 15, 542 | 27, 543 | 39, 544 | 51, 545 | 63, 546 | 75, 547 | 87, 548 | 99, 549 | 111 550 | ] 551 | }, 552 | { 553 | "index": 7, 554 | "name": "田宅", 555 | "isBodyPalace": false, 556 | "isOriginalPalace": false, 557 | "heavenlyStem": "乙", 558 | "earthlyBranch": "酉", 559 | "majorStars": [], 560 | "minorStars": [ 561 | { 562 | "name": "地空", 563 | "type": "tough", 564 | "scope": "origin", 565 | "brightness": "", 566 | "mutagen": null 567 | }, 568 | { 569 | "name": "擎羊", 570 | "type": "tough", 571 | "scope": "origin", 572 | "brightness": "陷", 573 | "mutagen": null 574 | } 575 | ], 576 | "adjectiveStars": [ 577 | { 578 | "name": "咸池", 579 | "type": "flower", 580 | "scope": "origin", 581 | "brightness": null, 582 | "mutagen": null 583 | }, 584 | { 585 | "name": "天贵", 586 | "type": "adjective", 587 | "scope": "origin", 588 | "brightness": null, 589 | "mutagen": null 590 | }, 591 | { 592 | "name": "月德", 593 | "type": "adjective", 594 | "scope": "origin", 595 | "brightness": null, 596 | "mutagen": null 597 | } 598 | ], 599 | "changsheng12": "冠带", 600 | "boshi12": "官府", 601 | "jiangqian12": "咸池", 602 | "suiqian12": "小耗", 603 | "decadal": { 604 | "range": [ 605 | 93, 606 | 102 607 | ], 608 | "heavenlyStem": "乙", 609 | "earthlyBranch": "酉" 610 | }, 611 | "ages": [ 612 | 2, 613 | 14, 614 | 26, 615 | 38, 616 | 50, 617 | 62, 618 | 74, 619 | 86, 620 | 98, 621 | 110 622 | ] 623 | }, 624 | { 625 | "index": 8, 626 | "name": "官禄", 627 | "isBodyPalace": true, 628 | "isOriginalPalace": false, 629 | "heavenlyStem": "丙", 630 | "earthlyBranch": "戌", 631 | "majorStars": [ 632 | { 633 | "name": "廉贞", 634 | "type": "major", 635 | "scope": "origin", 636 | "brightness": "利", 637 | "mutagen": "" 638 | }, 639 | { 640 | "name": "天府", 641 | "type": "major", 642 | "scope": "origin", 643 | "brightness": "庙", 644 | "mutagen": "" 645 | } 646 | ], 647 | "minorStars": [ 648 | { 649 | "name": "左辅", 650 | "type": "soft", 651 | "scope": "origin", 652 | "brightness": "", 653 | "mutagen": "" 654 | } 655 | ], 656 | "adjectiveStars": [ 657 | { 658 | "name": "天才", 659 | "type": "adjective", 660 | "scope": "origin", 661 | "brightness": null, 662 | "mutagen": null 663 | }, 664 | { 665 | "name": "天虚", 666 | "type": "adjective", 667 | "scope": "origin", 668 | "brightness": null, 669 | "mutagen": null 670 | } 671 | ], 672 | "changsheng12": "沐浴", 673 | "boshi12": "伏兵", 674 | "jiangqian12": "月煞", 675 | "suiqian12": "大耗", 676 | "decadal": { 677 | "range": [ 678 | 83, 679 | 92 680 | ], 681 | "heavenlyStem": "丙", 682 | "earthlyBranch": "戌" 683 | }, 684 | "ages": [ 685 | 1, 686 | 13, 687 | 25, 688 | 37, 689 | 49, 690 | 61, 691 | 73, 692 | 85, 693 | 97, 694 | 109 695 | ] 696 | }, 697 | { 698 | "index": 9, 699 | "name": "仆役", 700 | "isBodyPalace": false, 701 | "isOriginalPalace": false, 702 | "heavenlyStem": "丁", 703 | "earthlyBranch": "亥", 704 | "majorStars": [ 705 | { 706 | "name": "太阴", 707 | "type": "major", 708 | "scope": "origin", 709 | "brightness": "庙", 710 | "mutagen": "科" 711 | } 712 | ], 713 | "minorStars": [], 714 | "adjectiveStars": [ 715 | { 716 | "name": "红鸾", 717 | "type": "flower", 718 | "scope": "origin", 719 | "brightness": null, 720 | "mutagen": null 721 | }, 722 | { 723 | "name": "恩光", 724 | "type": "adjective", 725 | "scope": "origin", 726 | "brightness": null, 727 | "mutagen": null 728 | }, 729 | { 730 | "name": "天官", 731 | "type": "adjective", 732 | "scope": "origin", 733 | "brightness": null, 734 | "mutagen": null 735 | }, 736 | { 737 | "name": "天月", 738 | "type": "adjective", 739 | "scope": "origin", 740 | "brightness": null, 741 | "mutagen": null 742 | }, 743 | { 744 | "name": "天伤", 745 | "type": "adjective", 746 | "scope": "origin", 747 | "brightness": null, 748 | "mutagen": null 749 | } 750 | ], 751 | "changsheng12": "长生", 752 | "boshi12": "大耗", 753 | "jiangqian12": "亡神", 754 | "suiqian12": "龙德", 755 | "decadal": { 756 | "range": [ 757 | 73, 758 | 82 759 | ], 760 | "heavenlyStem": "丁", 761 | "earthlyBranch": "亥" 762 | }, 763 | "ages": [ 764 | 12, 765 | 24, 766 | 36, 767 | 48, 768 | 60, 769 | 72, 770 | 84, 771 | 96, 772 | 108, 773 | 120 774 | ] 775 | }, 776 | { 777 | "index": 10, 778 | "name": "迁移", 779 | "isBodyPalace": false, 780 | "isOriginalPalace": false, 781 | "heavenlyStem": "戊", 782 | "earthlyBranch": "子", 783 | "majorStars": [ 784 | { 785 | "name": "贪狼", 786 | "type": "major", 787 | "scope": "origin", 788 | "brightness": "旺", 789 | "mutagen": "" 790 | } 791 | ], 792 | "minorStars": [ 793 | { 794 | "name": "铃星", 795 | "type": "tough", 796 | "scope": "origin", 797 | "brightness": "陷", 798 | "mutagen": null 799 | } 800 | ], 801 | "adjectiveStars": [ 802 | { 803 | "name": "八座", 804 | "type": "adjective", 805 | "scope": "origin", 806 | "brightness": null, 807 | "mutagen": null 808 | } 809 | ], 810 | "changsheng12": "养", 811 | "boshi12": "病符", 812 | "jiangqian12": "将星", 813 | "suiqian12": "白虎", 814 | "decadal": { 815 | "range": [ 816 | 63, 817 | 72 818 | ], 819 | "heavenlyStem": "戊", 820 | "earthlyBranch": "子" 821 | }, 822 | "ages": [ 823 | 11, 824 | 23, 825 | 35, 826 | 47, 827 | 59, 828 | 71, 829 | 83, 830 | 95, 831 | 107, 832 | 119 833 | ] 834 | }, 835 | { 836 | "index": 11, 837 | "name": "疾厄", 838 | "isBodyPalace": false, 839 | "isOriginalPalace": false, 840 | "heavenlyStem": "己", 841 | "earthlyBranch": "丑", 842 | "majorStars": [ 843 | { 844 | "name": "天同", 845 | "type": "major", 846 | "scope": "origin", 847 | "brightness": "不", 848 | "mutagen": "忌" 849 | }, 850 | { 851 | "name": "巨门", 852 | "type": "major", 853 | "scope": "origin", 854 | "brightness": "不", 855 | "mutagen": "" 856 | } 857 | ], 858 | "minorStars": [ 859 | { 860 | "name": "天魁", 861 | "type": "soft", 862 | "scope": "origin", 863 | "brightness": "", 864 | "mutagen": null 865 | }, 866 | { 867 | "name": "地劫", 868 | "type": "tough", 869 | "scope": "origin", 870 | "brightness": "", 871 | "mutagen": null 872 | } 873 | ], 874 | "adjectiveStars": [ 875 | { 876 | "name": "天德", 877 | "type": "adjective", 878 | "scope": "origin", 879 | "brightness": null, 880 | "mutagen": null 881 | }, 882 | { 883 | "name": "寡宿", 884 | "type": "adjective", 885 | "scope": "origin", 886 | "brightness": null, 887 | "mutagen": null 888 | }, 889 | { 890 | "name": "破碎", 891 | "type": "adjective", 892 | "scope": "origin", 893 | "brightness": null, 894 | "mutagen": null 895 | }, 896 | { 897 | "name": "天使", 898 | "type": "adjective", 899 | "scope": "origin", 900 | "brightness": null, 901 | "mutagen": null 902 | } 903 | ], 904 | "changsheng12": "胎", 905 | "boshi12": "喜神", 906 | "jiangqian12": "攀鞍", 907 | "suiqian12": "天德", 908 | "decadal": { 909 | "range": [ 910 | 53, 911 | 62 912 | ], 913 | "heavenlyStem": "己", 914 | "earthlyBranch": "丑" 915 | }, 916 | "ages": [ 917 | 10, 918 | 22, 919 | 34, 920 | 46, 921 | 58, 922 | 70, 923 | 82, 924 | 94, 925 | 106, 926 | 118 927 | ] 928 | } 929 | ] 930 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # py-iztro 3 | [![pypi](https://img.shields.io/badge/pypi-v0.1-blue)](https://pypi.org/project/py-iztro/) 4 | [![codecov](https://codecov.io/gh/JinyangWang27/py-iztro/graph/badge.svg?token=QFWA4XR1HC)](https://codecov.io/gh/JinyangWang27/py-iztro) 5 | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/x-haose/py-iztro) 6 | 7 | 著名紫微排盘工具[iztro](https://github.com/SylarLong/iztro)python版本,用法和原版完全一致 8 | 9 | 感觉好用的话麻烦给颗✨✨ 10 | 11 | ## 特性 12 | 13 | - 使用和原本完成一致 14 | - 使用python版js解释器之间运行源代码逻辑完成一致 15 | - 使用`pydantic`对代码模型进行完全注解及注释 16 | - 基于`iztro`版本:2.5.0 17 | - 积极开发接受建议,欢迎提`issues` 18 | 19 | 20 | ## 路线图 21 | 22 | - 实现`iztro`库常用的大部分方法 23 | - 提供快捷服务端api 24 | 25 | 26 | ## 安装 27 | 28 | 使用 pip 安装 py-iztro 29 | 30 | ```bash 31 | pip install py-iztro 32 | ``` 33 | 34 | ## Demo 35 | 36 | ### 基本排盘 37 | ```py 38 | from py_iztro import Astro 39 | 40 | 41 | def main(): 42 | astro = Astro() 43 | result = astro.by_solar("2000-8-16", 2, "女") 44 | print(result.model_dump_json(by_alias=True, indent=4)) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | 50 | ``` 51 | 52 | 运行结果: 53 | ``` 54 | /Users/haose/code/py-iztro/.venv/bin/python /Users/haose/code/py-iztro/src/tests/base.py 55 | { 56 | "gender": "女", 57 | "solarDate": "2000-8-16", 58 | "lunarDate": "二〇〇〇年七月十七", 59 | "chineseDate": "庚辰 甲申 丙午 庚寅", 60 | "time": "寅时", 61 | "timeRange": "03:00~05:00", 62 | "sign": "狮子座", 63 | "zodiac": "龙", 64 | "earthlyBranchOfSoulPalace": "午", 65 | "earthlyBranchOfBodyPalace": "戌", 66 | "soul": "破军", 67 | "body": "文昌", 68 | "fiveElementsClass": "木三局", 69 | "palaces": [ 70 | { 71 | "index": 0, 72 | "name": "财帛", 73 | "isBodyPalace": false, 74 | "isOriginalPalace": false, 75 | "heavenlyStem": "戊", 76 | "earthlyBranch": "寅", 77 | "majorStars": [ 78 | { 79 | "name": "武曲", 80 | "type": "major", 81 | "scope": "origin", 82 | "brightness": "得", 83 | "mutagen": "权" 84 | }, 85 | { 86 | "name": "天相", 87 | "type": "major", 88 | "scope": "origin", 89 | "brightness": "庙", 90 | "mutagen": "" 91 | }, 92 | { 93 | "name": "天马", 94 | "type": "tianma", 95 | "scope": "origin", 96 | "brightness": "", 97 | "mutagen": null 98 | } 99 | ], 100 | "minorStars": [], 101 | "adjectiveStars": [ 102 | { 103 | "name": "解神", 104 | "type": "helper", 105 | "scope": "origin", 106 | "brightness": null, 107 | "mutagen": null 108 | }, 109 | { 110 | "name": "三台", 111 | "type": "adjective", 112 | "scope": "origin", 113 | "brightness": null, 114 | "mutagen": null 115 | }, 116 | { 117 | "name": "天寿", 118 | "type": "adjective", 119 | "scope": "origin", 120 | "brightness": null, 121 | "mutagen": null 122 | }, 123 | { 124 | "name": "天巫", 125 | "type": "adjective", 126 | "scope": "origin", 127 | "brightness": null, 128 | "mutagen": null 129 | }, 130 | { 131 | "name": "天厨", 132 | "type": "adjective", 133 | "scope": "origin", 134 | "brightness": null, 135 | "mutagen": null 136 | }, 137 | { 138 | "name": "阴煞", 139 | "type": "adjective", 140 | "scope": "origin", 141 | "brightness": null, 142 | "mutagen": null 143 | }, 144 | { 145 | "name": "天哭", 146 | "type": "adjective", 147 | "scope": "origin", 148 | "brightness": null, 149 | "mutagen": null 150 | } 151 | ], 152 | "changsheng12": "绝", 153 | "boshi12": "飞廉", 154 | "jiangqian12": "岁驿", 155 | "suiqian12": "吊客", 156 | "decadal": { 157 | "range": [ 158 | 43, 159 | 52 160 | ], 161 | "heavenlyStem": "戊", 162 | "earthlyBranch": "寅" 163 | }, 164 | "ages": [ 165 | 9, 166 | 21, 167 | 33, 168 | 45, 169 | 57, 170 | 69, 171 | 81, 172 | 93, 173 | 105, 174 | 117 175 | ] 176 | }, 177 | { 178 | "index": 1, 179 | "name": "子女", 180 | "isBodyPalace": false, 181 | "isOriginalPalace": false, 182 | "heavenlyStem": "己", 183 | "earthlyBranch": "卯", 184 | "majorStars": [ 185 | { 186 | "name": "太阳", 187 | "type": "major", 188 | "scope": "origin", 189 | "brightness": "庙", 190 | "mutagen": "禄" 191 | }, 192 | { 193 | "name": "天梁", 194 | "type": "major", 195 | "scope": "origin", 196 | "brightness": "庙", 197 | "mutagen": "" 198 | } 199 | ], 200 | "minorStars": [], 201 | "adjectiveStars": [ 202 | { 203 | "name": "天刑", 204 | "type": "adjective", 205 | "scope": "origin", 206 | "brightness": null, 207 | "mutagen": null 208 | } 209 | ], 210 | "changsheng12": "墓", 211 | "boshi12": "奏书", 212 | "jiangqian12": "息神", 213 | "suiqian12": "病符", 214 | "decadal": { 215 | "range": [ 216 | 33, 217 | 42 218 | ], 219 | "heavenlyStem": "己", 220 | "earthlyBranch": "卯" 221 | }, 222 | "ages": [ 223 | 8, 224 | 20, 225 | 32, 226 | 44, 227 | 56, 228 | 68, 229 | 80, 230 | 92, 231 | 104, 232 | 116 233 | ] 234 | }, 235 | { 236 | "index": 2, 237 | "name": "夫妻", 238 | "isBodyPalace": false, 239 | "isOriginalPalace": true, 240 | "heavenlyStem": "庚", 241 | "earthlyBranch": "辰", 242 | "majorStars": [ 243 | { 244 | "name": "七杀", 245 | "type": "major", 246 | "scope": "origin", 247 | "brightness": "庙", 248 | "mutagen": "" 249 | } 250 | ], 251 | "minorStars": [ 252 | { 253 | "name": "右弼", 254 | "type": "soft", 255 | "scope": "origin", 256 | "brightness": "", 257 | "mutagen": "" 258 | }, 259 | { 260 | "name": "火星", 261 | "type": "tough", 262 | "scope": "origin", 263 | "brightness": "陷", 264 | "mutagen": null 265 | } 266 | ], 267 | "adjectiveStars": [ 268 | { 269 | "name": "封诰", 270 | "type": "adjective", 271 | "scope": "origin", 272 | "brightness": null, 273 | "mutagen": null 274 | }, 275 | { 276 | "name": "华盖", 277 | "type": "adjective", 278 | "scope": "origin", 279 | "brightness": null, 280 | "mutagen": null 281 | } 282 | ], 283 | "changsheng12": "死", 284 | "boshi12": "将军", 285 | "jiangqian12": "华盖", 286 | "suiqian12": "岁建", 287 | "decadal": { 288 | "range": [ 289 | 23, 290 | 32 291 | ], 292 | "heavenlyStem": "庚", 293 | "earthlyBranch": "辰" 294 | }, 295 | "ages": [ 296 | 7, 297 | 19, 298 | 31, 299 | 43, 300 | 55, 301 | 67, 302 | 79, 303 | 91, 304 | 103, 305 | 115 306 | ] 307 | }, 308 | { 309 | "index": 3, 310 | "name": "兄弟", 311 | "isBodyPalace": false, 312 | "isOriginalPalace": false, 313 | "heavenlyStem": "辛", 314 | "earthlyBranch": "巳", 315 | "majorStars": [ 316 | { 317 | "name": "天机", 318 | "type": "major", 319 | "scope": "origin", 320 | "brightness": "平", 321 | "mutagen": "" 322 | } 323 | ], 324 | "minorStars": [], 325 | "adjectiveStars": [ 326 | { 327 | "name": "天喜", 328 | "type": "flower", 329 | "scope": "origin", 330 | "brightness": null, 331 | "mutagen": null 332 | }, 333 | { 334 | "name": "天空", 335 | "type": "adjective", 336 | "scope": "origin", 337 | "brightness": null, 338 | "mutagen": null 339 | }, 340 | { 341 | "name": "孤辰", 342 | "type": "adjective", 343 | "scope": "origin", 344 | "brightness": null, 345 | "mutagen": null 346 | } 347 | ], 348 | "changsheng12": "病", 349 | "boshi12": "小耗", 350 | "jiangqian12": "劫煞", 351 | "suiqian12": "晦气", 352 | "decadal": { 353 | "range": [ 354 | 13, 355 | 22 356 | ], 357 | "heavenlyStem": "辛", 358 | "earthlyBranch": "巳" 359 | }, 360 | "ages": [ 361 | 6, 362 | 18, 363 | 30, 364 | 42, 365 | 54, 366 | 66, 367 | 78, 368 | 90, 369 | 102, 370 | 114 371 | ] 372 | }, 373 | { 374 | "index": 4, 375 | "name": "命宫", 376 | "isBodyPalace": false, 377 | "isOriginalPalace": false, 378 | "heavenlyStem": "壬", 379 | "earthlyBranch": "午", 380 | "majorStars": [ 381 | { 382 | "name": "紫微", 383 | "type": "major", 384 | "scope": "origin", 385 | "brightness": "庙", 386 | "mutagen": "" 387 | } 388 | ], 389 | "minorStars": [ 390 | { 391 | "name": "文曲", 392 | "type": "soft", 393 | "scope": "origin", 394 | "brightness": "陷", 395 | "mutagen": "" 396 | } 397 | ], 398 | "adjectiveStars": [ 399 | { 400 | "name": "凤阁", 401 | "type": "adjective", 402 | "scope": "origin", 403 | "brightness": null, 404 | "mutagen": null 405 | }, 406 | { 407 | "name": "天福", 408 | "type": "adjective", 409 | "scope": "origin", 410 | "brightness": null, 411 | "mutagen": null 412 | }, 413 | { 414 | "name": "截空", 415 | "type": "adjective", 416 | "scope": "origin", 417 | "brightness": null, 418 | "mutagen": null 419 | }, 420 | { 421 | "name": "蜚廉", 422 | "type": "adjective", 423 | "scope": "origin", 424 | "brightness": null, 425 | "mutagen": null 426 | } 427 | ], 428 | "changsheng12": "衰", 429 | "boshi12": "青龙", 430 | "jiangqian12": "灾煞", 431 | "suiqian12": "丧门", 432 | "decadal": { 433 | "range": [ 434 | 3, 435 | 12 436 | ], 437 | "heavenlyStem": "壬", 438 | "earthlyBranch": "午" 439 | }, 440 | "ages": [ 441 | 5, 442 | 17, 443 | 29, 444 | 41, 445 | 53, 446 | 65, 447 | 77, 448 | 89, 449 | 101, 450 | 113 451 | ] 452 | }, 453 | { 454 | "index": 5, 455 | "name": "父母", 456 | "isBodyPalace": false, 457 | "isOriginalPalace": false, 458 | "heavenlyStem": "癸", 459 | "earthlyBranch": "未", 460 | "majorStars": [], 461 | "minorStars": [ 462 | { 463 | "name": "天钺", 464 | "type": "soft", 465 | "scope": "origin", 466 | "brightness": "", 467 | "mutagen": null 468 | }, 469 | { 470 | "name": "陀罗", 471 | "type": "tough", 472 | "scope": "origin", 473 | "brightness": "庙", 474 | "mutagen": null 475 | } 476 | ], 477 | "adjectiveStars": [ 478 | { 479 | "name": "天姚", 480 | "type": "flower", 481 | "scope": "origin", 482 | "brightness": null, 483 | "mutagen": null 484 | }, 485 | { 486 | "name": "空亡", 487 | "type": "adjective", 488 | "scope": "origin", 489 | "brightness": null, 490 | "mutagen": null 491 | } 492 | ], 493 | "changsheng12": "帝旺", 494 | "boshi12": "力士", 495 | "jiangqian12": "天煞", 496 | "suiqian12": "贯索", 497 | "decadal": { 498 | "range": [ 499 | 113, 500 | 122 501 | ], 502 | "heavenlyStem": "癸", 503 | "earthlyBranch": "未" 504 | }, 505 | "ages": [ 506 | 4, 507 | 16, 508 | 28, 509 | 40, 510 | 52, 511 | 64, 512 | 76, 513 | 88, 514 | 100, 515 | 112 516 | ] 517 | }, 518 | { 519 | "index": 6, 520 | "name": "福德", 521 | "isBodyPalace": false, 522 | "isOriginalPalace": false, 523 | "heavenlyStem": "甲", 524 | "earthlyBranch": "申", 525 | "majorStars": [ 526 | { 527 | "name": "破军", 528 | "type": "major", 529 | "scope": "origin", 530 | "brightness": "得", 531 | "mutagen": "" 532 | }, 533 | { 534 | "name": "禄存", 535 | "type": "lucun", 536 | "scope": "origin", 537 | "brightness": "", 538 | "mutagen": null 539 | } 540 | ], 541 | "minorStars": [ 542 | { 543 | "name": "文昌", 544 | "type": "soft", 545 | "scope": "origin", 546 | "brightness": "得", 547 | "mutagen": "" 548 | } 549 | ], 550 | "adjectiveStars": [ 551 | { 552 | "name": "龙池", 553 | "type": "adjective", 554 | "scope": "origin", 555 | "brightness": null, 556 | "mutagen": null 557 | }, 558 | { 559 | "name": "台辅", 560 | "type": "adjective", 561 | "scope": "origin", 562 | "brightness": null, 563 | "mutagen": null 564 | }, 565 | { 566 | "name": "旬空", 567 | "type": "adjective", 568 | "scope": "origin", 569 | "brightness": null, 570 | "mutagen": null 571 | } 572 | ], 573 | "changsheng12": "临官", 574 | "boshi12": "博士", 575 | "jiangqian12": "指背", 576 | "suiqian12": "官符", 577 | "decadal": { 578 | "range": [ 579 | 103, 580 | 112 581 | ], 582 | "heavenlyStem": "甲", 583 | "earthlyBranch": "申" 584 | }, 585 | "ages": [ 586 | 3, 587 | 15, 588 | 27, 589 | 39, 590 | 51, 591 | 63, 592 | 75, 593 | 87, 594 | 99, 595 | 111 596 | ] 597 | }, 598 | { 599 | "index": 7, 600 | "name": "田宅", 601 | "isBodyPalace": false, 602 | "isOriginalPalace": false, 603 | "heavenlyStem": "乙", 604 | "earthlyBranch": "酉", 605 | "majorStars": [], 606 | "minorStars": [ 607 | { 608 | "name": "地空", 609 | "type": "tough", 610 | "scope": "origin", 611 | "brightness": "", 612 | "mutagen": null 613 | }, 614 | { 615 | "name": "擎羊", 616 | "type": "tough", 617 | "scope": "origin", 618 | "brightness": "陷", 619 | "mutagen": null 620 | } 621 | ], 622 | "adjectiveStars": [ 623 | { 624 | "name": "咸池", 625 | "type": "flower", 626 | "scope": "origin", 627 | "brightness": null, 628 | "mutagen": null 629 | }, 630 | { 631 | "name": "天贵", 632 | "type": "adjective", 633 | "scope": "origin", 634 | "brightness": null, 635 | "mutagen": null 636 | }, 637 | { 638 | "name": "月德", 639 | "type": "adjective", 640 | "scope": "origin", 641 | "brightness": null, 642 | "mutagen": null 643 | } 644 | ], 645 | "changsheng12": "冠带", 646 | "boshi12": "官府", 647 | "jiangqian12": "咸池", 648 | "suiqian12": "小耗", 649 | "decadal": { 650 | "range": [ 651 | 93, 652 | 102 653 | ], 654 | "heavenlyStem": "乙", 655 | "earthlyBranch": "酉" 656 | }, 657 | "ages": [ 658 | 2, 659 | 14, 660 | 26, 661 | 38, 662 | 50, 663 | 62, 664 | 74, 665 | 86, 666 | 98, 667 | 110 668 | ] 669 | }, 670 | { 671 | "index": 8, 672 | "name": "官禄", 673 | "isBodyPalace": true, 674 | "isOriginalPalace": false, 675 | "heavenlyStem": "丙", 676 | "earthlyBranch": "戌", 677 | "majorStars": [ 678 | { 679 | "name": "廉贞", 680 | "type": "major", 681 | "scope": "origin", 682 | "brightness": "利", 683 | "mutagen": "" 684 | }, 685 | { 686 | "name": "天府", 687 | "type": "major", 688 | "scope": "origin", 689 | "brightness": "庙", 690 | "mutagen": "" 691 | } 692 | ], 693 | "minorStars": [ 694 | { 695 | "name": "左辅", 696 | "type": "soft", 697 | "scope": "origin", 698 | "brightness": "", 699 | "mutagen": "" 700 | } 701 | ], 702 | "adjectiveStars": [ 703 | { 704 | "name": "天才", 705 | "type": "adjective", 706 | "scope": "origin", 707 | "brightness": null, 708 | "mutagen": null 709 | }, 710 | { 711 | "name": "天虚", 712 | "type": "adjective", 713 | "scope": "origin", 714 | "brightness": null, 715 | "mutagen": null 716 | } 717 | ], 718 | "changsheng12": "沐浴", 719 | "boshi12": "伏兵", 720 | "jiangqian12": "月煞", 721 | "suiqian12": "大耗", 722 | "decadal": { 723 | "range": [ 724 | 83, 725 | 92 726 | ], 727 | "heavenlyStem": "丙", 728 | "earthlyBranch": "戌" 729 | }, 730 | "ages": [ 731 | 1, 732 | 13, 733 | 25, 734 | 37, 735 | 49, 736 | 61, 737 | 73, 738 | 85, 739 | 97, 740 | 109 741 | ] 742 | }, 743 | { 744 | "index": 9, 745 | "name": "仆役", 746 | "isBodyPalace": false, 747 | "isOriginalPalace": false, 748 | "heavenlyStem": "丁", 749 | "earthlyBranch": "亥", 750 | "majorStars": [ 751 | { 752 | "name": "太阴", 753 | "type": "major", 754 | "scope": "origin", 755 | "brightness": "庙", 756 | "mutagen": "科" 757 | } 758 | ], 759 | "minorStars": [], 760 | "adjectiveStars": [ 761 | { 762 | "name": "红鸾", 763 | "type": "flower", 764 | "scope": "origin", 765 | "brightness": null, 766 | "mutagen": null 767 | }, 768 | { 769 | "name": "恩光", 770 | "type": "adjective", 771 | "scope": "origin", 772 | "brightness": null, 773 | "mutagen": null 774 | }, 775 | { 776 | "name": "天官", 777 | "type": "adjective", 778 | "scope": "origin", 779 | "brightness": null, 780 | "mutagen": null 781 | }, 782 | { 783 | "name": "天月", 784 | "type": "adjective", 785 | "scope": "origin", 786 | "brightness": null, 787 | "mutagen": null 788 | }, 789 | { 790 | "name": "天伤", 791 | "type": "adjective", 792 | "scope": "origin", 793 | "brightness": null, 794 | "mutagen": null 795 | } 796 | ], 797 | "changsheng12": "长生", 798 | "boshi12": "大耗", 799 | "jiangqian12": "亡神", 800 | "suiqian12": "龙德", 801 | "decadal": { 802 | "range": [ 803 | 73, 804 | 82 805 | ], 806 | "heavenlyStem": "丁", 807 | "earthlyBranch": "亥" 808 | }, 809 | "ages": [ 810 | 12, 811 | 24, 812 | 36, 813 | 48, 814 | 60, 815 | 72, 816 | 84, 817 | 96, 818 | 108, 819 | 120 820 | ] 821 | }, 822 | { 823 | "index": 10, 824 | "name": "迁移", 825 | "isBodyPalace": false, 826 | "isOriginalPalace": false, 827 | "heavenlyStem": "戊", 828 | "earthlyBranch": "子", 829 | "majorStars": [ 830 | { 831 | "name": "贪狼", 832 | "type": "major", 833 | "scope": "origin", 834 | "brightness": "旺", 835 | "mutagen": "" 836 | } 837 | ], 838 | "minorStars": [ 839 | { 840 | "name": "铃星", 841 | "type": "tough", 842 | "scope": "origin", 843 | "brightness": "陷", 844 | "mutagen": null 845 | } 846 | ], 847 | "adjectiveStars": [ 848 | { 849 | "name": "八座", 850 | "type": "adjective", 851 | "scope": "origin", 852 | "brightness": null, 853 | "mutagen": null 854 | } 855 | ], 856 | "changsheng12": "养", 857 | "boshi12": "病符", 858 | "jiangqian12": "将星", 859 | "suiqian12": "白虎", 860 | "decadal": { 861 | "range": [ 862 | 63, 863 | 72 864 | ], 865 | "heavenlyStem": "戊", 866 | "earthlyBranch": "子" 867 | }, 868 | "ages": [ 869 | 11, 870 | 23, 871 | 35, 872 | 47, 873 | 59, 874 | 71, 875 | 83, 876 | 95, 877 | 107, 878 | 119 879 | ] 880 | }, 881 | { 882 | "index": 11, 883 | "name": "疾厄", 884 | "isBodyPalace": false, 885 | "isOriginalPalace": false, 886 | "heavenlyStem": "己", 887 | "earthlyBranch": "丑", 888 | "majorStars": [ 889 | { 890 | "name": "天同", 891 | "type": "major", 892 | "scope": "origin", 893 | "brightness": "不", 894 | "mutagen": "忌" 895 | }, 896 | { 897 | "name": "巨门", 898 | "type": "major", 899 | "scope": "origin", 900 | "brightness": "不", 901 | "mutagen": "" 902 | } 903 | ], 904 | "minorStars": [ 905 | { 906 | "name": "天魁", 907 | "type": "soft", 908 | "scope": "origin", 909 | "brightness": "", 910 | "mutagen": null 911 | }, 912 | { 913 | "name": "地劫", 914 | "type": "tough", 915 | "scope": "origin", 916 | "brightness": "", 917 | "mutagen": null 918 | } 919 | ], 920 | "adjectiveStars": [ 921 | { 922 | "name": "天德", 923 | "type": "adjective", 924 | "scope": "origin", 925 | "brightness": null, 926 | "mutagen": null 927 | }, 928 | { 929 | "name": "寡宿", 930 | "type": "adjective", 931 | "scope": "origin", 932 | "brightness": null, 933 | "mutagen": null 934 | }, 935 | { 936 | "name": "破碎", 937 | "type": "adjective", 938 | "scope": "origin", 939 | "brightness": null, 940 | "mutagen": null 941 | }, 942 | { 943 | "name": "天使", 944 | "type": "adjective", 945 | "scope": "origin", 946 | "brightness": null, 947 | "mutagen": null 948 | } 949 | ], 950 | "changsheng12": "胎", 951 | "boshi12": "喜神", 952 | "jiangqian12": "攀鞍", 953 | "suiqian12": "天德", 954 | "decadal": { 955 | "range": [ 956 | 53, 957 | 62 958 | ], 959 | "heavenlyStem": "己", 960 | "earthlyBranch": "丑" 961 | }, 962 | "ages": [ 963 | 10, 964 | 22, 965 | 34, 966 | 46, 967 | 58, 968 | 70, 969 | 82, 970 | 94, 971 | 106, 972 | 118 973 | ] 974 | } 975 | ] 976 | } 977 | 978 | 进程已结束,退出代码为 0 979 | 980 | ``` 981 | 982 | ### 大限流年 983 | 984 | ```py 985 | from py_iztro import Astro 986 | 987 | 988 | def main(): 989 | astro = Astro() 990 | result = astro.by_solar("2000-8-16", 2, "女") 991 | result = result.horoscope("2025-01-01").model_dump_json(by_alias=True, indent=4) 992 | print(result) 993 | 994 | 995 | if __name__ == '__main__': 996 | main() 997 | ``` 998 | 999 | 运行结果: 1000 | ``` 1001 | /Users/haose/code/py-iztro/.venv/bin/python /Users/haose/code/py-iztro/src/tests/daxian.py 1002 | { 1003 | "lunarDate": "二〇二四年腊月初二", 1004 | "solarDate": "2025-1-1", 1005 | "decadal": { 1006 | "index": 2, 1007 | "name": "大限", 1008 | "heavenlyStem": "庚", 1009 | "earthlyBranch": "辰", 1010 | "palaceNames": [ 1011 | "夫妻", 1012 | "兄弟", 1013 | "命宫", 1014 | "父母", 1015 | "福德", 1016 | "田宅", 1017 | "官禄", 1018 | "仆役", 1019 | "迁移", 1020 | "疾厄", 1021 | "财帛", 1022 | "子女" 1023 | ], 1024 | "mutagen": [ 1025 | "太阳", 1026 | "武曲", 1027 | "太阴", 1028 | "天同" 1029 | ], 1030 | "stars": [ 1031 | [ 1032 | { 1033 | "name": "运马", 1034 | "type": "tianma", 1035 | "scope": "decadal", 1036 | "brightness": null, 1037 | "mutagen": null 1038 | } 1039 | ], 1040 | [ 1041 | { 1042 | "name": "运曲", 1043 | "type": "soft", 1044 | "scope": "decadal", 1045 | "brightness": null, 1046 | "mutagen": null 1047 | } 1048 | ], 1049 | [], 1050 | [ 1051 | { 1052 | "name": "运喜", 1053 | "type": "flower", 1054 | "scope": "decadal", 1055 | "brightness": null, 1056 | "mutagen": null 1057 | } 1058 | ], 1059 | [], 1060 | [ 1061 | { 1062 | "name": "运钺", 1063 | "type": "soft", 1064 | "scope": "decadal", 1065 | "brightness": null, 1066 | "mutagen": null 1067 | }, 1068 | { 1069 | "name": "运陀", 1070 | "type": "tough", 1071 | "scope": "decadal", 1072 | "brightness": null, 1073 | "mutagen": null 1074 | } 1075 | ], 1076 | [ 1077 | { 1078 | "name": "运禄", 1079 | "type": "lucun", 1080 | "scope": "decadal", 1081 | "brightness": null, 1082 | "mutagen": null 1083 | } 1084 | ], 1085 | [ 1086 | { 1087 | "name": "运羊", 1088 | "type": "tough", 1089 | "scope": "decadal", 1090 | "brightness": null, 1091 | "mutagen": null 1092 | } 1093 | ], 1094 | [], 1095 | [ 1096 | { 1097 | "name": "运昌", 1098 | "type": "soft", 1099 | "scope": "decadal", 1100 | "brightness": null, 1101 | "mutagen": null 1102 | }, 1103 | { 1104 | "name": "运鸾", 1105 | "type": "flower", 1106 | "scope": "decadal", 1107 | "brightness": null, 1108 | "mutagen": null 1109 | } 1110 | ], 1111 | [], 1112 | [ 1113 | { 1114 | "name": "运魁", 1115 | "type": "soft", 1116 | "scope": "decadal", 1117 | "brightness": null, 1118 | "mutagen": null 1119 | } 1120 | ] 1121 | ] 1122 | }, 1123 | "age": { 1124 | "index": 8, 1125 | "name": "小限", 1126 | "heavenlyStem": "丙", 1127 | "earthlyBranch": "戌", 1128 | "palaceNames": [ 1129 | "官禄", 1130 | "仆役", 1131 | "迁移", 1132 | "疾厄", 1133 | "财帛", 1134 | "子女", 1135 | "夫妻", 1136 | "兄弟", 1137 | "命宫", 1138 | "父母", 1139 | "福德", 1140 | "田宅" 1141 | ], 1142 | "mutagen": [ 1143 | "天同", 1144 | "天机", 1145 | "文昌", 1146 | "廉贞" 1147 | ], 1148 | "stars": [], 1149 | "nominalAge": 25 1150 | }, 1151 | "yearly": { 1152 | "index": 2, 1153 | "name": "流年", 1154 | "heavenlyStem": "甲", 1155 | "earthlyBranch": "辰", 1156 | "palaceNames": [ 1157 | "夫妻", 1158 | "兄弟", 1159 | "命宫", 1160 | "父母", 1161 | "福德", 1162 | "田宅", 1163 | "官禄", 1164 | "仆役", 1165 | "迁移", 1166 | "疾厄", 1167 | "财帛", 1168 | "子女" 1169 | ], 1170 | "mutagen": [ 1171 | "廉贞", 1172 | "破军", 1173 | "武曲", 1174 | "太阳" 1175 | ], 1176 | "stars": [ 1177 | [ 1178 | { 1179 | "name": "流禄", 1180 | "type": "lucun", 1181 | "scope": "yearly", 1182 | "brightness": null, 1183 | "mutagen": null 1184 | }, 1185 | { 1186 | "name": "流马", 1187 | "type": "tianma", 1188 | "scope": "yearly", 1189 | "brightness": null, 1190 | "mutagen": null 1191 | } 1192 | ], 1193 | [ 1194 | { 1195 | "name": "流羊", 1196 | "type": "tough", 1197 | "scope": "yearly", 1198 | "brightness": null, 1199 | "mutagen": null 1200 | } 1201 | ], 1202 | [], 1203 | [ 1204 | { 1205 | "name": "流昌", 1206 | "type": "soft", 1207 | "scope": "yearly", 1208 | "brightness": null, 1209 | "mutagen": null 1210 | }, 1211 | { 1212 | "name": "流喜", 1213 | "type": "flower", 1214 | "scope": "yearly", 1215 | "brightness": null, 1216 | "mutagen": null 1217 | } 1218 | ], 1219 | [ 1220 | { 1221 | "name": "年解", 1222 | "type": "helper", 1223 | "scope": "yearly", 1224 | "brightness": null, 1225 | "mutagen": null 1226 | } 1227 | ], 1228 | [ 1229 | { 1230 | "name": "流钺", 1231 | "type": "soft", 1232 | "scope": "yearly", 1233 | "brightness": null, 1234 | "mutagen": null 1235 | } 1236 | ], 1237 | [], 1238 | [ 1239 | { 1240 | "name": "流曲", 1241 | "type": "soft", 1242 | "scope": "yearly", 1243 | "brightness": null, 1244 | "mutagen": null 1245 | } 1246 | ], 1247 | [], 1248 | [ 1249 | { 1250 | "name": "流鸾", 1251 | "type": "flower", 1252 | "scope": "yearly", 1253 | "brightness": null, 1254 | "mutagen": null 1255 | } 1256 | ], 1257 | [], 1258 | [ 1259 | { 1260 | "name": "流魁", 1261 | "type": "soft", 1262 | "scope": "yearly", 1263 | "brightness": null, 1264 | "mutagen": null 1265 | }, 1266 | { 1267 | "name": "流陀", 1268 | "type": "tough", 1269 | "scope": "yearly", 1270 | "brightness": null, 1271 | "mutagen": null 1272 | } 1273 | ] 1274 | ], 1275 | "yearlyDecStar": { 1276 | "jiangqian12": [ 1277 | "岁驿", 1278 | "息神", 1279 | "华盖", 1280 | "劫煞", 1281 | "灾煞", 1282 | "天煞", 1283 | "指背", 1284 | "咸池", 1285 | "月煞", 1286 | "亡神", 1287 | "将星", 1288 | "攀鞍" 1289 | ], 1290 | "suiqian12": [ 1291 | "吊客", 1292 | "病符", 1293 | "岁建", 1294 | "晦气", 1295 | "丧门", 1296 | "贯索", 1297 | "官符", 1298 | "小耗", 1299 | "大耗", 1300 | "龙德", 1301 | "白虎", 1302 | "天德" 1303 | ] 1304 | } 1305 | }, 1306 | "monthly": { 1307 | "index": 8, 1308 | "name": "流月", 1309 | "heavenlyStem": "丙", 1310 | "earthlyBranch": "子", 1311 | "palaceNames": [ 1312 | "官禄", 1313 | "仆役", 1314 | "迁移", 1315 | "疾厄", 1316 | "财帛", 1317 | "子女", 1318 | "夫妻", 1319 | "兄弟", 1320 | "命宫", 1321 | "父母", 1322 | "福德", 1323 | "田宅" 1324 | ], 1325 | "mutagen": [ 1326 | "天同", 1327 | "天机", 1328 | "文昌", 1329 | "廉贞" 1330 | ], 1331 | "stars": [ 1332 | [ 1333 | { 1334 | "name": "yuema", 1335 | "type": "tianma", 1336 | "scope": "monthly", 1337 | "brightness": null, 1338 | "mutagen": null 1339 | } 1340 | ], 1341 | [ 1342 | { 1343 | "name": "yueluan", 1344 | "type": "flower", 1345 | "scope": "monthly", 1346 | "brightness": null, 1347 | "mutagen": null 1348 | } 1349 | ], 1350 | [ 1351 | { 1352 | "name": "yuetuo", 1353 | "type": "tough", 1354 | "scope": "monthly", 1355 | "brightness": null, 1356 | "mutagen": null 1357 | } 1358 | ], 1359 | [ 1360 | { 1361 | "name": "yuelu", 1362 | "type": "lucun", 1363 | "scope": "monthly", 1364 | "brightness": null, 1365 | "mutagen": null 1366 | } 1367 | ], 1368 | [ 1369 | { 1370 | "name": "yuequ", 1371 | "type": "soft", 1372 | "scope": "monthly", 1373 | "brightness": null, 1374 | "mutagen": null 1375 | }, 1376 | { 1377 | "name": "yueyang", 1378 | "type": "tough", 1379 | "scope": "monthly", 1380 | "brightness": null, 1381 | "mutagen": null 1382 | } 1383 | ], 1384 | [], 1385 | [ 1386 | { 1387 | "name": "yuechang", 1388 | "type": "soft", 1389 | "scope": "monthly", 1390 | "brightness": null, 1391 | "mutagen": null 1392 | } 1393 | ], 1394 | [ 1395 | { 1396 | "name": "yueyue", 1397 | "type": "soft", 1398 | "scope": "monthly", 1399 | "brightness": null, 1400 | "mutagen": null 1401 | }, 1402 | { 1403 | "name": "yuexi", 1404 | "type": "flower", 1405 | "scope": "monthly", 1406 | "brightness": null, 1407 | "mutagen": null 1408 | } 1409 | ], 1410 | [], 1411 | [ 1412 | { 1413 | "name": "yuekui", 1414 | "type": "soft", 1415 | "scope": "monthly", 1416 | "brightness": null, 1417 | "mutagen": null 1418 | } 1419 | ], 1420 | [], 1421 | [] 1422 | ] 1423 | }, 1424 | "daily": { 1425 | "index": 9, 1426 | "name": "流日", 1427 | "heavenlyStem": "庚", 1428 | "earthlyBranch": "午", 1429 | "palaceNames": [ 1430 | "田宅", 1431 | "官禄", 1432 | "仆役", 1433 | "迁移", 1434 | "疾厄", 1435 | "财帛", 1436 | "子女", 1437 | "夫妻", 1438 | "兄弟", 1439 | "命宫", 1440 | "父母", 1441 | "福德" 1442 | ], 1443 | "mutagen": [ 1444 | "太阳", 1445 | "武曲", 1446 | "太阴", 1447 | "天同" 1448 | ], 1449 | "stars": [ 1450 | [], 1451 | [ 1452 | { 1453 | "name": "riqu", 1454 | "type": "soft", 1455 | "scope": "daily", 1456 | "brightness": null, 1457 | "mutagen": null 1458 | }, 1459 | { 1460 | "name": "rixi", 1461 | "type": "flower", 1462 | "scope": "daily", 1463 | "brightness": null, 1464 | "mutagen": null 1465 | } 1466 | ], 1467 | [], 1468 | [], 1469 | [], 1470 | [ 1471 | { 1472 | "name": "riyue", 1473 | "type": "soft", 1474 | "scope": "daily", 1475 | "brightness": null, 1476 | "mutagen": null 1477 | }, 1478 | { 1479 | "name": "rituo", 1480 | "type": "tough", 1481 | "scope": "daily", 1482 | "brightness": null, 1483 | "mutagen": null 1484 | } 1485 | ], 1486 | [ 1487 | { 1488 | "name": "rilu", 1489 | "type": "lucun", 1490 | "scope": "daily", 1491 | "brightness": null, 1492 | "mutagen": null 1493 | }, 1494 | { 1495 | "name": "rima", 1496 | "type": "tianma", 1497 | "scope": "daily", 1498 | "brightness": null, 1499 | "mutagen": null 1500 | } 1501 | ], 1502 | [ 1503 | { 1504 | "name": "riyang", 1505 | "type": "tough", 1506 | "scope": "daily", 1507 | "brightness": null, 1508 | "mutagen": null 1509 | }, 1510 | { 1511 | "name": "riluan", 1512 | "type": "flower", 1513 | "scope": "daily", 1514 | "brightness": null, 1515 | "mutagen": null 1516 | } 1517 | ], 1518 | [], 1519 | [ 1520 | { 1521 | "name": "richang", 1522 | "type": "soft", 1523 | "scope": "daily", 1524 | "brightness": null, 1525 | "mutagen": null 1526 | } 1527 | ], 1528 | [], 1529 | [ 1530 | { 1531 | "name": "rikui", 1532 | "type": "soft", 1533 | "scope": "daily", 1534 | "brightness": null, 1535 | "mutagen": null 1536 | } 1537 | ] 1538 | ] 1539 | }, 1540 | "hourly": { 1541 | "index": 9, 1542 | "name": "流时", 1543 | "heavenlyStem": "丙", 1544 | "earthlyBranch": "子", 1545 | "palaceNames": [ 1546 | "田宅", 1547 | "官禄", 1548 | "仆役", 1549 | "迁移", 1550 | "疾厄", 1551 | "财帛", 1552 | "子女", 1553 | "夫妻", 1554 | "兄弟", 1555 | "命宫", 1556 | "父母", 1557 | "福德" 1558 | ], 1559 | "mutagen": [ 1560 | "天同", 1561 | "天机", 1562 | "文昌", 1563 | "廉贞" 1564 | ], 1565 | "stars": [ 1566 | [ 1567 | { 1568 | "name": "shima", 1569 | "type": "tianma", 1570 | "scope": "hourly", 1571 | "brightness": null, 1572 | "mutagen": null 1573 | } 1574 | ], 1575 | [ 1576 | { 1577 | "name": "shiluan", 1578 | "type": "flower", 1579 | "scope": "hourly", 1580 | "brightness": null, 1581 | "mutagen": null 1582 | } 1583 | ], 1584 | [ 1585 | { 1586 | "name": "shituo", 1587 | "type": "tough", 1588 | "scope": "hourly", 1589 | "brightness": null, 1590 | "mutagen": null 1591 | } 1592 | ], 1593 | [ 1594 | { 1595 | "name": "shilu", 1596 | "type": "lucun", 1597 | "scope": "hourly", 1598 | "brightness": null, 1599 | "mutagen": null 1600 | } 1601 | ], 1602 | [ 1603 | { 1604 | "name": "shiqu", 1605 | "type": "soft", 1606 | "scope": "hourly", 1607 | "brightness": null, 1608 | "mutagen": null 1609 | }, 1610 | { 1611 | "name": "shiyang", 1612 | "type": "tough", 1613 | "scope": "hourly", 1614 | "brightness": null, 1615 | "mutagen": null 1616 | } 1617 | ], 1618 | [], 1619 | [ 1620 | { 1621 | "name": "shichang", 1622 | "type": "soft", 1623 | "scope": "hourly", 1624 | "brightness": null, 1625 | "mutagen": null 1626 | } 1627 | ], 1628 | [ 1629 | { 1630 | "name": "shiyue", 1631 | "type": "soft", 1632 | "scope": "hourly", 1633 | "brightness": null, 1634 | "mutagen": null 1635 | }, 1636 | { 1637 | "name": "shixi", 1638 | "type": "flower", 1639 | "scope": "hourly", 1640 | "brightness": null, 1641 | "mutagen": null 1642 | } 1643 | ], 1644 | [], 1645 | [ 1646 | { 1647 | "name": "shikui", 1648 | "type": "soft", 1649 | "scope": "hourly", 1650 | "brightness": null, 1651 | "mutagen": null 1652 | } 1653 | ], 1654 | [], 1655 | [] 1656 | ] 1657 | } 1658 | } 1659 | 1660 | 进程已结束,退出代码为 0 1661 | 1662 | ``` 1663 | 1664 | ## 作者 1665 | 1666 | - [@haose](https://www.github.com/x-haose) 1667 | 1668 | 1669 | ## 致谢 1670 | 1671 | - [最好的紫微排盘工具:iztro](https://github.com/SylarLong/iztro) 1672 | --------------------------------------------------------------------------------