# sajupy
사주팔자 만세력 계산을 위한 Python 라이브러리입니다.
## 특징
- **정확한 사주팔자 계산**: 1900년부터 2100년까지의 만세력 데이터 기반
- **음력/양력 변환**: 음력과 양력 간 자유로운 날짜 변환
- **태양시 보정**: 출생 지역의 경도를 고려한 정확한 시간 계산
- **전 세계 도시 지원**: 도시 이름으로 자동 경도 조회
- **절기 시간 고려**: 절기 시간을 정확히 반영한 월주 계산
- **조자시/야자시 처리**: 23시-01시 구간의 정확한 시주 계산
## 설치
```bash
pip install sajupy
```
## 빠른 시작
```python
from sajupy import calculate_saju
# 기본 사용법
result = calculate_saju(1990, 10, 10, 14, 30)
print(result)
# 태양시 보정을 사용한 계산
result = calculate_saju(
year=1990,
month=10,
day=10,
hour=14,
minute=30,
city="Seoul", # 또는 longitude=126.9780
use_solar_time=True
)
print(result)
```
## 주요 기능
### 1. 만세력 계산
```python
from sajupy import SajuCalculator
calculator = SajuCalculator()
# 상세 옵션을 사용한 사주 계산
saju = calculator.calculate_saju(
year=1990,
month=10,
day=10,
hour=14,
minute=30,
city="Seoul", # 도시 이름으로 경도 자동 조회
use_solar_time=True, # 태양시 보정 사용
utc_offset=9, # UTC 오프셋 (서울)
early_zi_time=True # 조자시 사용 (00:00-01:00을 당일로)
)
print(f"연주: {saju['year_pillar']}")
print(f"월주: {saju['month_pillar']}")
print(f"일주: {saju['day_pillar']}")
print(f"시주: {saju['hour_pillar']}")
```
### 2. 음력/양력 변환
```python
from sajupy import solar_to_lunar, lunar_to_solar
# 양력을 음력으로 변환
lunar_date = solar_to_lunar(2024, 1, 1)
print(lunar_date)
# {
# "lunar_year": 2023,
# "lunar_month": 11,
# "lunar_day": 20,
# "is_leap_month": false,
# "solar_date": "2024-01-01"
# }
# 음력을 양력으로 변환
solar_date = lunar_to_solar(2023, 11, 20)
print(solar_date)
# {
# "solar_year": 2024,
# "solar_month": 1,
# "solar_day": 1,
# "solar_date": "2024-01-01",
# "lunar_date": "2023년 11월 20일"
# }
```
### 3. 음력 월 정보 조회
```python
from sajupy import get_lunar_month_info
# 음력 월의 일수 및 윤달 정보 조회
month_info = get_lunar_month_info(2023, 2)
print(month_info)
# {
# "lunar_year": 2023,
# "lunar_month": 2,
# "has_leap_month": true,
# "regular_month_days": 29,
# "leap_month_days": 30
# }
```
## 출력 형식
`calculate_saju` 함수는 다음과 같은 딕셔너리 결과를 반환합니다:
```json
{
"year_pillar": "庚午",
"month_pillar": "丙戌",
"day_pillar": "己未",
"hour_pillar": "辛未",
"year_stem": "庚",
"year_branch": "午",
"month_stem": "丙",
"month_branch": "戌",
"day_stem": "己",
"day_branch": "未",
"hour_stem": "辛",
"hour_branch": "未",
"birth_time": "14:30",
"birth_date": "1990-10-10",
"zi_time_type": null,
"solar_correction": {
"city": "Seoul",
"longitude": 126.9780,
"longitude_source": "geocoded",
"utc_offset": 9,
"standard_longitude": 135,
"correction_minutes": -32.1,
"original_time": "14:30",
"solar_time": "13:58"
}
}
```
## 고급 사용법
### SajuCalculator 클래스 직접 사용
```python
from sajupy import SajuCalculator
# 커스텀 데이터 파일 사용
calculator = SajuCalculator(csv_path='my_custom_data.csv')
# datetime 객체로 계산
from datetime import datetime
dt = datetime(1990, 10, 10, 14, 30)
saju = calculator.calculate_saju_from_datetime(dt, city="Seoul")
```
### 태양시 보정 상세 설정
```python
# 경도를 직접 지정
saju = calculate_saju(
year=1990, month=10, day=10, hour=14, minute=30,
longitude=126.9780, # 서울의 경도
use_solar_time=True,
utc_offset=9
)
# 해외 도시 예시
saju = calculate_saju(
year=1990, month=10, day=10, hour=14, minute=30,
city="Los Angeles",
use_solar_time=True,
utc_offset=-8 # 태평양 표준시
)
```
## 주의사항
- 데이터 범위: 1900년 ~ 2100년
- 시간은 24시간 형식 사용 (0-23)
- 태양시 보정 시 정확한 출생 지역 정보 필요
- 윤달 처리 시 `is_leap_month` 파라미터 확인 필요
## 라이선스
이 프로젝트는 MIT 라이선스를 따릅니다. 자세한 내용은 [LICENSE](LICENSE) 파일을 참조하세요.
## 기여
버그 리포트, 기능 제안, 풀 리퀘스트를 환영합니다!
[이슈](https://github.com/0ssw1/sajupy/issues)를 생성하거나 풀 리퀘스트를 보내주세요.
Raw data
{
"_id": null,
"home_page": "https://github.com/0ssw1/sajupy",
"name": "sajupy",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "saju, korean-calendar, lunar-calendar, \uc0ac\uc8fc\ud314\uc790, \uc0ac\uc8fc, \uc74c\ub825, \uc591\ub825, \ub9cc\uc138\ub825, bazi",
"author": "Suh Seungwan",
"author_email": "Suh Seungwan <suh@yumeta.kr>",
"download_url": "https://files.pythonhosted.org/packages/59/c0/9bf4e72a0123568b8009a81dd1329efde8d27b585dfe82cda0485c51d926/sajupy-0.2.0.tar.gz",
"platform": null,
"description": "# sajupy\n\n\uc0ac\uc8fc\ud314\uc790 \ub9cc\uc138\ub825 \uacc4\uc0b0\uc744 \uc704\ud55c Python \ub77c\uc774\ube0c\ub7ec\ub9ac\uc785\ub2c8\ub2e4.\n\n## \ud2b9\uc9d5\n\n- **\uc815\ud655\ud55c \uc0ac\uc8fc\ud314\uc790 \uacc4\uc0b0**: 1900\ub144\ubd80\ud130 2100\ub144\uae4c\uc9c0\uc758 \ub9cc\uc138\ub825 \ub370\uc774\ud130 \uae30\ubc18\n- **\uc74c\ub825/\uc591\ub825 \ubcc0\ud658**: \uc74c\ub825\uacfc \uc591\ub825 \uac04 \uc790\uc720\ub85c\uc6b4 \ub0a0\uc9dc \ubcc0\ud658\n- **\ud0dc\uc591\uc2dc \ubcf4\uc815**: \ucd9c\uc0dd \uc9c0\uc5ed\uc758 \uacbd\ub3c4\ub97c \uace0\ub824\ud55c \uc815\ud655\ud55c \uc2dc\uac04 \uacc4\uc0b0\n- **\uc804 \uc138\uacc4 \ub3c4\uc2dc \uc9c0\uc6d0**: \ub3c4\uc2dc \uc774\ub984\uc73c\ub85c \uc790\ub3d9 \uacbd\ub3c4 \uc870\ud68c\n- **\uc808\uae30 \uc2dc\uac04 \uace0\ub824**: \uc808\uae30 \uc2dc\uac04\uc744 \uc815\ud655\ud788 \ubc18\uc601\ud55c \uc6d4\uc8fc \uacc4\uc0b0\n- **\uc870\uc790\uc2dc/\uc57c\uc790\uc2dc \ucc98\ub9ac**: 23\uc2dc-01\uc2dc \uad6c\uac04\uc758 \uc815\ud655\ud55c \uc2dc\uc8fc \uacc4\uc0b0\n\n## \uc124\uce58\n\n```bash\npip install sajupy\n```\n\n## \ube60\ub978 \uc2dc\uc791\n\n```python\nfrom sajupy import calculate_saju\n\n# \uae30\ubcf8 \uc0ac\uc6a9\ubc95\nresult = calculate_saju(1990, 10, 10, 14, 30)\nprint(result)\n\n# \ud0dc\uc591\uc2dc \ubcf4\uc815\uc744 \uc0ac\uc6a9\ud55c \uacc4\uc0b0\nresult = calculate_saju(\n year=1990, \n month=10, \n day=10, \n hour=14, \n minute=30,\n city=\"Seoul\", # \ub610\ub294 longitude=126.9780\n use_solar_time=True\n)\nprint(result)\n```\n\n## \uc8fc\uc694 \uae30\ub2a5\n\n### 1. \ub9cc\uc138\ub825 \uacc4\uc0b0\n\n```python\nfrom sajupy import SajuCalculator\n\ncalculator = SajuCalculator()\n\n# \uc0c1\uc138 \uc635\uc158\uc744 \uc0ac\uc6a9\ud55c \uc0ac\uc8fc \uacc4\uc0b0\nsaju = calculator.calculate_saju(\n year=1990,\n month=10,\n day=10,\n hour=14,\n minute=30,\n city=\"Seoul\", # \ub3c4\uc2dc \uc774\ub984\uc73c\ub85c \uacbd\ub3c4 \uc790\ub3d9 \uc870\ud68c\n use_solar_time=True, # \ud0dc\uc591\uc2dc \ubcf4\uc815 \uc0ac\uc6a9\n utc_offset=9, # UTC \uc624\ud504\uc14b (\uc11c\uc6b8)\n early_zi_time=True # \uc870\uc790\uc2dc \uc0ac\uc6a9 (00:00-01:00\uc744 \ub2f9\uc77c\ub85c)\n)\n\nprint(f\"\uc5f0\uc8fc: {saju['year_pillar']}\")\nprint(f\"\uc6d4\uc8fc: {saju['month_pillar']}\")\nprint(f\"\uc77c\uc8fc: {saju['day_pillar']}\")\nprint(f\"\uc2dc\uc8fc: {saju['hour_pillar']}\")\n```\n\n### 2. \uc74c\ub825/\uc591\ub825 \ubcc0\ud658\n\n```python\nfrom sajupy import solar_to_lunar, lunar_to_solar\n\n# \uc591\ub825\uc744 \uc74c\ub825\uc73c\ub85c \ubcc0\ud658\nlunar_date = solar_to_lunar(2024, 1, 1)\nprint(lunar_date)\n# {\n# \"lunar_year\": 2023,\n# \"lunar_month\": 11,\n# \"lunar_day\": 20,\n# \"is_leap_month\": false,\n# \"solar_date\": \"2024-01-01\"\n# }\n\n# \uc74c\ub825\uc744 \uc591\ub825\uc73c\ub85c \ubcc0\ud658\nsolar_date = lunar_to_solar(2023, 11, 20)\nprint(solar_date)\n# {\n# \"solar_year\": 2024,\n# \"solar_month\": 1,\n# \"solar_day\": 1,\n# \"solar_date\": \"2024-01-01\",\n# \"lunar_date\": \"2023\ub144 11\uc6d4 20\uc77c\"\n# }\n```\n\n### 3. \uc74c\ub825 \uc6d4 \uc815\ubcf4 \uc870\ud68c\n\n```python\nfrom sajupy import get_lunar_month_info\n\n# \uc74c\ub825 \uc6d4\uc758 \uc77c\uc218 \ubc0f \uc724\ub2ec \uc815\ubcf4 \uc870\ud68c\nmonth_info = get_lunar_month_info(2023, 2)\nprint(month_info)\n# {\n# \"lunar_year\": 2023,\n# \"lunar_month\": 2,\n# \"has_leap_month\": true,\n# \"regular_month_days\": 29,\n# \"leap_month_days\": 30\n# }\n```\n\n## \ucd9c\ub825 \ud615\uc2dd\n\n`calculate_saju` \ud568\uc218\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \ub515\uc154\ub108\ub9ac \uacb0\uacfc\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4:\n\n```json\n{\n \"year_pillar\": \"\u5e9a\u5348\",\n \"month_pillar\": \"\u4e19\u620c\",\n \"day_pillar\": \"\u5df1\u672a\",\n \"hour_pillar\": \"\u8f9b\u672a\",\n \"year_stem\": \"\u5e9a\",\n \"year_branch\": \"\u5348\",\n \"month_stem\": \"\u4e19\",\n \"month_branch\": \"\u620c\",\n \"day_stem\": \"\u5df1\",\n \"day_branch\": \"\u672a\",\n \"hour_stem\": \"\u8f9b\",\n \"hour_branch\": \"\u672a\",\n \"birth_time\": \"14:30\",\n \"birth_date\": \"1990-10-10\",\n \"zi_time_type\": null,\n \"solar_correction\": {\n \"city\": \"Seoul\",\n \"longitude\": 126.9780,\n \"longitude_source\": \"geocoded\",\n \"utc_offset\": 9,\n \"standard_longitude\": 135,\n \"correction_minutes\": -32.1,\n \"original_time\": \"14:30\",\n \"solar_time\": \"13:58\"\n }\n}\n```\n\n## \uace0\uae09 \uc0ac\uc6a9\ubc95\n\n### SajuCalculator \ud074\ub798\uc2a4 \uc9c1\uc811 \uc0ac\uc6a9\n\n```python\nfrom sajupy import SajuCalculator\n\n# \ucee4\uc2a4\ud140 \ub370\uc774\ud130 \ud30c\uc77c \uc0ac\uc6a9\ncalculator = SajuCalculator(csv_path='my_custom_data.csv')\n\n# datetime \uac1d\uccb4\ub85c \uacc4\uc0b0\nfrom datetime import datetime\ndt = datetime(1990, 10, 10, 14, 30)\nsaju = calculator.calculate_saju_from_datetime(dt, city=\"Seoul\")\n```\n\n### \ud0dc\uc591\uc2dc \ubcf4\uc815 \uc0c1\uc138 \uc124\uc815\n\n```python\n# \uacbd\ub3c4\ub97c \uc9c1\uc811 \uc9c0\uc815\nsaju = calculate_saju(\n year=1990, month=10, day=10, hour=14, minute=30,\n longitude=126.9780, # \uc11c\uc6b8\uc758 \uacbd\ub3c4\n use_solar_time=True,\n utc_offset=9\n)\n\n# \ud574\uc678 \ub3c4\uc2dc \uc608\uc2dc\nsaju = calculate_saju(\n year=1990, month=10, day=10, hour=14, minute=30,\n city=\"Los Angeles\",\n use_solar_time=True,\n utc_offset=-8 # \ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc\n)\n```\n\n## \uc8fc\uc758\uc0ac\ud56d\n\n- \ub370\uc774\ud130 \ubc94\uc704: 1900\ub144 ~ 2100\ub144\n- \uc2dc\uac04\uc740 24\uc2dc\uac04 \ud615\uc2dd \uc0ac\uc6a9 (0-23)\n- \ud0dc\uc591\uc2dc \ubcf4\uc815 \uc2dc \uc815\ud655\ud55c \ucd9c\uc0dd \uc9c0\uc5ed \uc815\ubcf4 \ud544\uc694\n- \uc724\ub2ec \ucc98\ub9ac \uc2dc `is_leap_month` \ud30c\ub77c\ubbf8\ud130 \ud655\uc778 \ud544\uc694\n\n## \ub77c\uc774\uc120\uc2a4\n\n\uc774 \ud504\ub85c\uc81d\ud2b8\ub294 MIT \ub77c\uc774\uc120\uc2a4\ub97c \ub530\ub985\ub2c8\ub2e4. \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [LICENSE](LICENSE) \ud30c\uc77c\uc744 \ucc38\uc870\ud558\uc138\uc694.\n\n## \uae30\uc5ec\n\n\ubc84\uadf8 \ub9ac\ud3ec\ud2b8, \uae30\ub2a5 \uc81c\uc548, \ud480 \ub9ac\ud018\uc2a4\ud2b8\ub97c \ud658\uc601\ud569\ub2c8\ub2e4! \n[\uc774\uc288](https://github.com/0ssw1/sajupy/issues)\ub97c \uc0dd\uc131\ud558\uac70\ub098 \ud480 \ub9ac\ud018\uc2a4\ud2b8\ub97c \ubcf4\ub0b4\uc8fc\uc138\uc694.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\uc0ac\uc8fc\ud314\uc790 \ub9cc\uc138\ub825 \uacc4\uc0b0 \ub77c\uc774\ube0c\ub7ec\ub9ac",
"version": "0.2.0",
"project_urls": {
"Homepage": "https://github.com/0ssw1/sajupy"
},
"split_keywords": [
"saju",
" korean-calendar",
" lunar-calendar",
" \uc0ac\uc8fc\ud314\uc790",
" \uc0ac\uc8fc",
" \uc74c\ub825",
" \uc591\ub825",
" \ub9cc\uc138\ub825",
" bazi"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c49b742ccc44cf5be94fdf263c6f296722c2e1de18c9479631e432fddf873a27",
"md5": "8916b9329023bab8334bad0af6b4f3dd",
"sha256": "eaa57ee49da144d8fff76e525796a05a0814dc8523fbfb4a3a3aa0297aa2c877"
},
"downloads": -1,
"filename": "sajupy-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8916b9329023bab8334bad0af6b4f3dd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 650617,
"upload_time": "2025-07-27T17:41:45",
"upload_time_iso_8601": "2025-07-27T17:41:45.277267Z",
"url": "https://files.pythonhosted.org/packages/c4/9b/742ccc44cf5be94fdf263c6f296722c2e1de18c9479631e432fddf873a27/sajupy-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "59c09bf4e72a0123568b8009a81dd1329efde8d27b585dfe82cda0485c51d926",
"md5": "ec0907c41103a2597b4a2b6722b4ce40",
"sha256": "07b8e89222bb91d8c2b8d9454349460938583014b2b5f235da14b081a7773e3f"
},
"downloads": -1,
"filename": "sajupy-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "ec0907c41103a2597b4a2b6722b4ce40",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 657774,
"upload_time": "2025-07-27T17:41:46",
"upload_time_iso_8601": "2025-07-27T17:41:46.681698Z",
"url": "https://files.pythonhosted.org/packages/59/c0/9bf4e72a0123568b8009a81dd1329efde8d27b585dfe82cda0485c51d926/sajupy-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-27 17:41:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "0ssw1",
"github_project": "sajupy",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "pandas",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
">=",
"2.8.0"
]
]
},
{
"name": "geopy",
"specs": [
[
">=",
"2.3.0"
]
]
}
],
"lcname": "sajupy"
}