@gracefullight/saju 0.2.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.en.md +250 -32
  2. package/README.md +250 -32
  3. package/dist/__tests__/date-fns-adapter.test.js +1 -1
  4. package/dist/__tests__/four-pillars.test.js +10 -9
  5. package/dist/__tests__/luck.test.d.ts +2 -0
  6. package/dist/__tests__/luck.test.d.ts.map +1 -0
  7. package/dist/__tests__/luck.test.js +33 -0
  8. package/dist/__tests__/lunar.test.js +1 -1
  9. package/dist/__tests__/luxon-adapter.test.js +1 -1
  10. package/dist/__tests__/relations.test.d.ts +2 -0
  11. package/dist/__tests__/relations.test.d.ts.map +1 -0
  12. package/dist/__tests__/relations.test.js +90 -0
  13. package/dist/__tests__/saju.test.d.ts +2 -0
  14. package/dist/__tests__/saju.test.d.ts.map +1 -0
  15. package/dist/__tests__/saju.test.js +133 -0
  16. package/dist/__tests__/sinsals.test.d.ts +2 -0
  17. package/dist/__tests__/sinsals.test.d.ts.map +1 -0
  18. package/dist/__tests__/sinsals.test.js +64 -0
  19. package/dist/__tests__/solar-terms.test.d.ts +2 -0
  20. package/dist/__tests__/solar-terms.test.d.ts.map +1 -0
  21. package/dist/__tests__/solar-terms.test.js +121 -0
  22. package/dist/__tests__/strength.test.d.ts +2 -0
  23. package/dist/__tests__/strength.test.d.ts.map +1 -0
  24. package/dist/__tests__/strength.test.js +44 -0
  25. package/dist/__tests__/ten-gods.test.d.ts +2 -0
  26. package/dist/__tests__/ten-gods.test.d.ts.map +1 -0
  27. package/dist/__tests__/ten-gods.test.js +119 -0
  28. package/dist/__tests__/twelve-stages.test.d.ts +2 -0
  29. package/dist/__tests__/twelve-stages.test.d.ts.map +1 -0
  30. package/dist/__tests__/twelve-stages.test.js +86 -0
  31. package/dist/__tests__/utils.test.d.ts +2 -0
  32. package/dist/__tests__/utils.test.d.ts.map +1 -0
  33. package/dist/__tests__/utils.test.js +130 -0
  34. package/dist/__tests__/yongshen.test.d.ts +2 -0
  35. package/dist/__tests__/yongshen.test.d.ts.map +1 -0
  36. package/dist/__tests__/yongshen.test.js +62 -0
  37. package/dist/adapters/date-fns.d.ts +1 -1
  38. package/dist/adapters/luxon.d.ts +1 -1
  39. package/dist/core/four-pillars.d.ts +6 -6
  40. package/dist/core/four-pillars.d.ts.map +1 -1
  41. package/dist/core/four-pillars.js +10 -26
  42. package/dist/core/luck.d.ts +60 -0
  43. package/dist/core/luck.d.ts.map +1 -0
  44. package/dist/core/luck.js +137 -0
  45. package/dist/core/relations.d.ts +94 -0
  46. package/dist/core/relations.d.ts.map +1 -0
  47. package/dist/core/relations.js +309 -0
  48. package/dist/core/sinsals.d.ts +19 -0
  49. package/dist/core/sinsals.d.ts.map +1 -0
  50. package/dist/core/sinsals.js +339 -0
  51. package/dist/core/solar-terms.d.ts +155 -0
  52. package/dist/core/solar-terms.d.ts.map +1 -0
  53. package/dist/core/solar-terms.js +266 -0
  54. package/dist/core/strength.d.ts +18 -0
  55. package/dist/core/strength.d.ts.map +1 -0
  56. package/dist/core/strength.js +255 -0
  57. package/dist/core/ten-gods.d.ts +127 -0
  58. package/dist/core/ten-gods.d.ts.map +1 -0
  59. package/dist/core/ten-gods.js +331 -0
  60. package/dist/core/twelve-stages.d.ts +17 -0
  61. package/dist/core/twelve-stages.d.ts.map +1 -0
  62. package/dist/core/twelve-stages.js +77 -0
  63. package/dist/core/yongshen.d.ts +20 -0
  64. package/dist/core/yongshen.d.ts.map +1 -0
  65. package/dist/core/yongshen.js +216 -0
  66. package/dist/index.d.ts +63 -3
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +57 -2
  69. package/dist/types/common.d.ts +12 -0
  70. package/dist/types/common.d.ts.map +1 -0
  71. package/dist/types/common.js +1 -0
  72. package/dist/types/index.d.ts +2 -0
  73. package/dist/types/index.d.ts.map +1 -0
  74. package/dist/types/index.js +1 -0
  75. package/dist/utils/constants.d.ts +13 -0
  76. package/dist/utils/constants.d.ts.map +1 -0
  77. package/dist/utils/constants.js +59 -0
  78. package/dist/utils/index.d.ts +2 -0
  79. package/dist/utils/index.d.ts.map +1 -0
  80. package/dist/utils/index.js +1 -0
  81. package/package.json +13 -12
package/README.en.md CHANGED
@@ -15,7 +15,13 @@
15
15
  - **Solar Time Correction** - Optional mean solar time adjustment based on longitude
16
16
  - **Tree-shakeable** - Import only what you need
17
17
  - **Fully Typed** - Complete TypeScript definitions
18
- - **Well Tested** - 85+ tests with 91%+ coverage
18
+ - **Well Tested** - 180+ tests with 91%+ coverage
19
+ - **Ten Gods Analysis** - Detailed ten gods and five elements distribution with hidden stems
20
+ - **Strength Assessment** - 9-level strength analysis with monthly strength (得令), root strength (通根), transparency (透干), and hidden stem weights (本中餘氣)
21
+ - **Relations Analysis** - Combinations, clashes, harms, punishments with transformation (化) status and conditions
22
+ - **Major/Yearly Luck** - Solar term (節氣) based accurate luck start calculation, major luck and yearly luck based on gender and year pillar
23
+ - **Yongshen Extraction** - Favorable element recommendation following 格局→抑扶→調候 priority with fortune enhancement guide
24
+ - **Solar Terms Analysis** - Current/next solar term info with elapsed days calculation
19
25
 
20
26
  ## What is Saju (四柱)?
21
27
 
@@ -59,7 +65,7 @@ pnpm add date-fns date-fns-tz
59
65
  ```typescript
60
66
  import { DateTime } from "luxon";
61
67
  import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
62
- import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
68
+ import { getSaju } from "@gracefullight/saju";
63
69
 
64
70
  const adapter = await createLuxonAdapter();
65
71
 
@@ -68,30 +74,41 @@ const birthDateTime = DateTime.fromObject(
68
74
  { zone: "Asia/Seoul" }
69
75
  );
70
76
 
71
- const result = getFourPillars(adapter, birthDateTime, {
72
- longitudeDeg: 126.9778, // Seoul longitude
73
- preset: STANDARD_PRESET,
77
+ // getSaju: Calculate pillars, ten gods, strength, relations, yongshen, solar terms, major luck, yearly luck all at once
78
+ const result = getSaju(adapter, birthDateTime, {
79
+ gender: "male", // Required: needed for major luck calculation
80
+ // longitudeDeg: 126.9778, // Optional: uses timezone-based longitude if omitted
81
+ // preset: STANDARD_PRESET, // Optional: defaults to STANDARD_PRESET
82
+ // yearlyLuckRange: { from: 2024, to: 2030 }, // Optional: specify yearly luck range
74
83
  });
75
84
 
85
+ console.log(result.pillars); // { year: "己卯", month: "丙子", ... }
86
+ console.log(result.tenGods); // Ten gods and hidden stems analysis
87
+ console.log(result.strength); // Strength assessment (e.g., "weak")
88
+ console.log(result.relations); // Relations analysis
89
+ console.log(result.yongShen); // Yongshen and fortune tips
90
+ console.log(result.solarTerms); // Solar term info (current/next term, elapsed days)
91
+ console.log(result.majorLuck); // Major luck info
92
+ console.log(result.yearlyLuck); // Yearly luck info
93
+ ```
94
+
95
+ ### Calculate Four Pillars Only
96
+
97
+ ```typescript
98
+ import { DateTime } from "luxon";
99
+ import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
100
+ import { getFourPillars } from "@gracefullight/saju";
101
+
102
+ const adapter = await createLuxonAdapter();
103
+
104
+ const birthDateTime = DateTime.fromObject(
105
+ { year: 2000, month: 1, day: 1, hour: 18, minute: 0 },
106
+ { zone: "Asia/Seoul" }
107
+ );
108
+
109
+ const result = getFourPillars(adapter, birthDateTime);
110
+
76
111
  console.log(result);
77
- // {
78
- // year: "己卯", // Year Pillar (Heavenly Stem + Earthly Branch)
79
- // month: "丙子", // Month Pillar
80
- // day: "辛巳", // Day Pillar
81
- // hour: "戊戌", // Hour Pillar
82
- // lunar: {
83
- // lunarYear: 1999,
84
- // lunarMonth: 11,
85
- // lunarDay: 25,
86
- // isLeapMonth: false
87
- // },
88
- // meta: {
89
- // solarYearUsed: 1999,
90
- // sunLonDeg: 280.9,
91
- // effectiveDayDate: { year: 2000, month: 1, day: 1 },
92
- // adjustedDtForHour: "2000-01-01T18:00:00.000+09:00"
93
- // }
94
- // }
95
112
  ```
96
113
 
97
114
  ## Usage
@@ -206,12 +223,27 @@ Traditional interpretation with Zi hour (23:00) day boundary and solar time corr
206
223
  }
207
224
  ```
208
225
 
209
- #### Deprecated Aliases
210
- - `presetA` → Use `STANDARD_PRESET`
211
- - `presetB` → Use `TRADITIONAL_PRESET`
212
-
213
226
  ### Core Functions
214
227
 
228
+ #### `getSaju(adapter, datetime, options)`
229
+
230
+ Calculate all saju analysis results (pillars, ten gods, strength, relations, yongshen, solar terms, major luck, yearly luck) at once.
231
+
232
+ ```typescript
233
+ function getSaju<T>(
234
+ adapter: DateAdapter<T>,
235
+ dtLocal: T,
236
+ options: {
237
+ longitudeDeg: number;
238
+ gender: "male" | "female"; // Required
239
+ tzOffsetHours?: number;
240
+ preset?: typeof STANDARD_PRESET;
241
+ currentYear?: number; // For default yearly luck range
242
+ yearlyLuckRange?: { from: number; to: number }; // Specify yearly luck range directly
243
+ }
244
+ ): SajuResult;
245
+ ```
246
+
215
247
  #### `getFourPillars(adapter, datetime, options)`
216
248
 
217
249
  Calculate all four pillars (year, month, day, hour).
@@ -425,6 +457,109 @@ function effectiveDayDate<T>(
425
457
  }
426
458
  ```
427
459
 
460
+ ### Analysis Functions
461
+
462
+ #### `analyzeTenGods(year, month, day, hour)`
463
+
464
+ Analyzes ten gods and hidden stems of the four pillars.
465
+
466
+ ```typescript
467
+ function analyzeTenGods(
468
+ year: string,
469
+ month: string,
470
+ day: string,
471
+ hour: string
472
+ ): FourPillarsTenGods;
473
+ ```
474
+
475
+ #### `analyzeStrength(year, month, day, hour)`
476
+
477
+ Assesses the strength of the day master on a 7-level scale.
478
+
479
+ ```typescript
480
+ function analyzeStrength(
481
+ year: string,
482
+ month: string,
483
+ day: string,
484
+ hour: string
485
+ ): StrengthResult;
486
+ ```
487
+
488
+ #### `analyzeRelations(year, month, day, hour)`
489
+
490
+ Analyzes combinations, clashes, harms, and punishments between stems and branches.
491
+
492
+ ```typescript
493
+ function analyzeRelations(
494
+ year: string,
495
+ month: string,
496
+ day: string,
497
+ hour: string
498
+ ): RelationsResult;
499
+ ```
500
+
501
+ #### `calculateMajorLuck(adapter, datetime, gender, year, month)`
502
+
503
+ Calculates major luck periods and starting age.
504
+
505
+ ```typescript
506
+ function calculateMajorLuck<T>(
507
+ adapter: DateAdapter<T>,
508
+ birthDateTime: T,
509
+ gender: "male" | "female",
510
+ yearPillar: string,
511
+ monthPillar: string
512
+ ): MajorLuckResult;
513
+ ```
514
+
515
+ #### `analyzeYongShen(year, month, day, hour)`
516
+
517
+ Extracts favorable elements considering suppression and climate adjustment.
518
+
519
+ ```typescript
520
+ function analyzeYongShen(
521
+ year: string,
522
+ month: string,
523
+ day: string,
524
+ hour: string
525
+ ): YongShenResult;
526
+ ```
527
+
528
+ #### `analyzeSolarTerms(adapter, datetime)`
529
+
530
+ Calculates current and next solar term info with elapsed days.
531
+
532
+ ```typescript
533
+ function analyzeSolarTerms<T>(
534
+ adapter: DateAdapter<T>,
535
+ dtLocal: T
536
+ ): SolarTermInfo;
537
+ ```
538
+
539
+ **Returns:**
540
+ ```typescript
541
+ {
542
+ current: { name: "소한", hanja: "小寒", longitude: 285 },
543
+ currentDate: { year: 2024, month: 1, day: 6, hour: 5, minute: 30 },
544
+ daysSinceCurrent: 5,
545
+ next: { name: "대한", hanja: "大寒", longitude: 300 },
546
+ nextDate: { year: 2024, month: 1, day: 20, hour: 12, minute: 15 },
547
+ daysUntilNext: 10
548
+ }
549
+ ```
550
+
551
+ #### `getSolarTermsForYear(adapter, year, timezone)`
552
+
553
+ Calculates all 24 solar terms for a specific year.
554
+
555
+ ```typescript
556
+ function getSolarTermsForYear<T>(
557
+ adapter: DateAdapter<T>,
558
+ year: number,
559
+ timezone: string
560
+ ): Array<{ term: SolarTerm; date: {...} }>;
561
+ ```
562
+
428
563
  ## Advanced Usage
429
564
 
430
565
  ### Solar Time Correction
@@ -499,6 +634,85 @@ Common city longitudes for reference:
499
634
 
500
635
  ## Examples
501
636
 
637
+ ### Major and Yearly Luck Calculation
638
+
639
+ ```typescript
640
+ const saju = getSaju(adapter, dt, {
641
+ longitudeDeg: 126.9778,
642
+ gender: "female",
643
+ yearlyLuckRange: { from: 2024, to: 2030 }
644
+ });
645
+
646
+ // Check major luck
647
+ console.log(saju.majorLuck.pillars); // Major luck pillars list
648
+ console.log(saju.majorLuck.startAge); // Starting age for major luck
649
+
650
+ // Check yearly luck
651
+ saju.yearlyLuck.forEach(luck => {
652
+ console.log(`Year ${luck.year} (${luck.pillar}): Age ${luck.age}`);
653
+ });
654
+ ```
655
+
656
+ ### Solar Terms Info
657
+
658
+ ```typescript
659
+ const saju = getSaju(adapter, dt, {
660
+ longitudeDeg: 126.9778,
661
+ gender: "male",
662
+ });
663
+
664
+ // Current solar term
665
+ console.log(saju.solarTerms.current.name); // "소한"
666
+ console.log(saju.solarTerms.current.hanja); // "小寒"
667
+ console.log(saju.solarTerms.daysSinceCurrent); // 5 (days since term started)
668
+
669
+ // Next solar term
670
+ console.log(saju.solarTerms.next.name); // "대한"
671
+ console.log(saju.solarTerms.daysUntilNext); // 10 (days until next term)
672
+
673
+ // Solar term dates
674
+ console.log(saju.solarTerms.currentDate); // { year: 2024, month: 1, day: 6, ... }
675
+ console.log(saju.solarTerms.nextDate); // { year: 2024, month: 1, day: 20, ... }
676
+ ```
677
+
678
+ ### Ten Gods and Five Elements Analysis
679
+
680
+ ```typescript
681
+ import { analyzeTenGods, countElements } from "@gracefullight/saju";
682
+
683
+ const tenGods = analyzeTenGods("己卯", "丙子", "辛巳", "戊戌");
684
+ console.log(tenGods.dayMaster); // "辛"
685
+
686
+ const elements = countElements(tenGods);
687
+ console.log(elements); // { wood: 1, fire: 1, earth: 3, metal: 1, water: 2 }
688
+ ```
689
+
690
+ ### Strength and Yongshen Analysis
691
+
692
+ ```typescript
693
+ import { analyzeStrength, analyzeYongShen, getElementRecommendations } from "@gracefullight/saju";
694
+
695
+ const strength = analyzeStrength("己卯", "丙子", "辛巳", "戊戌");
696
+ console.log(strength.level); // "weak"
697
+
698
+ const yongShen = analyzeYongShen("己卯", "丙子", "辛巳", "戊戌");
699
+ console.log(yongShen.primary); // Favorable element (e.g., "earth")
700
+
701
+ const tips = getElementRecommendations(yongShen);
702
+ console.log(tips.colors); // Lucky colors
703
+ ```
704
+
705
+ ### Relations Analysis
706
+
707
+ ```typescript
708
+ import { analyzeRelations } from "@gracefullight/saju";
709
+
710
+ const relations = analyzeRelations("己卯", "丙子", "辛巳", "戊戌");
711
+ relations.clashes.forEach(c => {
712
+ console.log(`${c.positions[0]}-${c.positions[1]} branch clash: ${c.pair[0]}-${c.pair[1]}`);
713
+ });
714
+ ```
715
+
502
716
  ### Calculate for Different Timezones
503
717
 
504
718
  ```typescript
@@ -606,7 +820,15 @@ packages/saju/
606
820
  │ │ ├── luxon.ts # Luxon adapter
607
821
  │ │ └── date-fns.ts # date-fns adapter
608
822
  │ ├── core/ # Core calculation logic
609
- │ │ └── four-pillars.ts # Main algorithms
823
+ │ │ ├── four-pillars.ts # Four pillars calculation
824
+ │ │ ├── ten-gods.ts # Ten gods analysis
825
+ │ │ ├── strength.ts # Strength assessment
826
+ │ │ ├── relations.ts # Relations analysis
827
+ │ │ ├── luck.ts # Major/yearly luck
828
+ │ │ ├── yongshen.ts # Yongshen extraction
829
+ │ │ ├── solar-terms.ts # Solar terms calculation
830
+ │ │ └── lunar.ts # Lunar conversion
831
+ │ ├── types/ # Type definitions
610
832
  │ ├── __tests__/ # Test suites
611
833
  │ └── index.ts # Public API
612
834
  ├── dist/ # Compiled output
@@ -723,7 +945,3 @@ This library is based on traditional Chinese calendar algorithms and astronomica
723
945
  - [Documentation](https://github.com/gracefullight/saju#readme)
724
946
  - [Issue Tracker](https://github.com/gracefullight/saju/issues)
725
947
  - [Discussions](https://github.com/gracefullight/saju/discussions)
726
-
727
- ---
728
-
729
- Made by [gracefullight](https://github.com/gracefullight)
package/README.md CHANGED
@@ -15,7 +15,13 @@
15
15
  - **태양시 보정** - 경도 기반 평균 태양시 조정 옵션
16
16
  - **트리쉐이킹 지원** - 필요한 것만 import
17
17
  - **완전한 타입 지원** - TypeScript 정의 완비
18
- - **풍부한 테스트** - 85개 이상 테스트, 91% 이상 커버리지
18
+ - **풍부한 테스트** - 180개 이상 테스트, 91% 이상 커버리지
19
+ - **십신 분석** - 장간(藏干)을 포함한 상세 십신 및 오행 분포 분석
20
+ - **신강/신약 판정** - 월령 득령(得令), 통근(通根), 투간(透干), 본중여기(本中餘氣) 가중치를 고려한 9단계 신강도 분석
21
+ - **합충형파해** - 천간합, 육합, 삼합, 방합 및 충, 해, 형, 파 분석. 합(合)과 화(化) 성립 조건 분리 표기
22
+ - **대운/세운 계산** - 절기(節氣) 기반 정확한 기운(起運) 계산, 성별 및 연간 음양을 고려한 대운 및 연도별 세운 계산
23
+ - **용신 추출** - 격국(格局), 억부(抑扶), 조후(調候) 순서로 용신 추천 및 개운법 가이드
24
+ - **절기 분석** - 현재/다음 절기 정보 및 경과일 계산
19
25
 
20
26
  ## 사주(四柱)란?
21
27
 
@@ -59,7 +65,7 @@ pnpm add date-fns date-fns-tz
59
65
  ```typescript
60
66
  import { DateTime } from "luxon";
61
67
  import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
62
- import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
68
+ import { getSaju } from "@gracefullight/saju";
63
69
 
64
70
  const adapter = await createLuxonAdapter();
65
71
 
@@ -68,30 +74,41 @@ const birthDateTime = DateTime.fromObject(
68
74
  { zone: "Asia/Seoul" }
69
75
  );
70
76
 
71
- const result = getFourPillars(adapter, birthDateTime, {
72
- longitudeDeg: 126.9778, // 서울 경도
73
- preset: STANDARD_PRESET,
77
+ // getSaju: 사주 팔자, 십신, 신강약, 합충, 용신, 절기, 대운, 세운을 한 번에 계산
78
+ const result = getSaju(adapter, birthDateTime, {
79
+ gender: "male", // 필수: 대운 계산에 필요
80
+ // longitudeDeg: 126.9778, // 선택: 생략 시 타임존 기준 경도 사용
81
+ // preset: STANDARD_PRESET, // 선택: 기본값은 STANDARD_PRESET
82
+ // yearlyLuckRange: { from: 2024, to: 2030 }, // 선택: 세운 범위 지정
74
83
  });
75
84
 
85
+ console.log(result.pillars); // { year: "己卯", month: "丙子", ... }
86
+ console.log(result.tenGods); // 십신 및 장간 분석
87
+ console.log(result.strength); // 신강/신약 판정 (예: "신약")
88
+ console.log(result.relations); // 합충형파해 분석
89
+ console.log(result.yongShen); // 용신 및 개운법
90
+ console.log(result.solarTerms); // 절기 정보 (현재/다음 절기, 경과일)
91
+ console.log(result.majorLuck); // 대운 정보
92
+ console.log(result.yearlyLuck); // 세운 정보
93
+ ```
94
+
95
+ ### 사주 팔자만 계산하기
96
+
97
+ ```typescript
98
+ import { DateTime } from "luxon";
99
+ import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
100
+ import { getFourPillars } from "@gracefullight/saju";
101
+
102
+ const adapter = await createLuxonAdapter();
103
+
104
+ const birthDateTime = DateTime.fromObject(
105
+ { year: 2000, month: 1, day: 1, hour: 18, minute: 0 },
106
+ { zone: "Asia/Seoul" }
107
+ );
108
+
109
+ const result = getFourPillars(adapter, birthDateTime);
110
+
76
111
  console.log(result);
77
- // {
78
- // year: "己卯", // 연주 (천간 + 지지)
79
- // month: "丙子", // 월주
80
- // day: "辛巳", // 일주
81
- // hour: "戊戌", // 시주
82
- // lunar: {
83
- // lunarYear: 1999,
84
- // lunarMonth: 11,
85
- // lunarDay: 25,
86
- // isLeapMonth: false
87
- // },
88
- // meta: {
89
- // solarYearUsed: 1999,
90
- // sunLonDeg: 280.9,
91
- // effectiveDayDate: { year: 2000, month: 1, day: 1 },
92
- // adjustedDtForHour: "2000-01-01T18:00:00.000+09:00"
93
- // }
94
- // }
95
112
  ```
96
113
 
97
114
  ## 사용법
@@ -206,12 +223,27 @@ const myAdapter: DateAdapter<MyDateType> = {
206
223
  }
207
224
  ```
208
225
 
209
- #### 사용 중단된 별칭
210
- - `presetA` → `STANDARD_PRESET` 사용 권장
211
- - `presetB` → `TRADITIONAL_PRESET` 사용 권장
212
-
213
226
  ### 핵심 함수
214
227
 
228
+ #### `getSaju(adapter, datetime, options)`
229
+
230
+ 사주 분석의 모든 결과(팔자, 십신, 신강약, 합충, 용신, 대운)를 한 번에 계산합니다.
231
+
232
+ ```typescript
233
+ function getSaju<T>(
234
+ adapter: DateAdapter<T>,
235
+ dtLocal: T,
236
+ options: {
237
+ longitudeDeg: number;
238
+ gender: "male" | "female"; // 필수
239
+ tzOffsetHours?: number;
240
+ preset?: typeof STANDARD_PRESET;
241
+ currentYear?: number; // 세운 기본 범위 계산용
242
+ yearlyLuckRange?: { from: number; to: number }; // 세운 범위 직접 지정
243
+ }
244
+ ): SajuResult;
245
+ ```
246
+
215
247
  #### `getFourPillars(adapter, datetime, options)`
216
248
 
217
249
  네 기둥(연주, 월주, 일주, 시주) 모두 계산
@@ -425,6 +457,109 @@ function effectiveDayDate<T>(
425
457
  }
426
458
  ```
427
459
 
460
+ ### 분석 함수
461
+
462
+ #### `analyzeTenGods(year, month, day, hour)`
463
+
464
+ 사주 팔자의 십신과 지장간을 분석합니다.
465
+
466
+ ```typescript
467
+ function analyzeTenGods(
468
+ year: string,
469
+ month: string,
470
+ day: string,
471
+ hour: string
472
+ ): FourPillarsTenGods;
473
+ ```
474
+
475
+ #### `analyzeStrength(year, month, day, hour)`
476
+
477
+ 사주의 신강/신약을 9단계로 판정합니다.
478
+
479
+ ```typescript
480
+ function analyzeStrength(
481
+ year: string,
482
+ month: string,
483
+ day: string,
484
+ hour: string
485
+ ): StrengthResult;
486
+ ```
487
+
488
+ #### `analyzeRelations(year, month, day, hour)`
489
+
490
+ 천간과 지지의 합, 충, 형, 파, 해 관계를 분석합니다.
491
+
492
+ ```typescript
493
+ function analyzeRelations(
494
+ year: string,
495
+ month: string,
496
+ day: string,
497
+ hour: string
498
+ ): RelationsResult;
499
+ ```
500
+
501
+ #### `calculateMajorLuck(adapter, datetime, gender, year, month)`
502
+
503
+ 대운의 흐름과 시작 연령을 계산합니다.
504
+
505
+ ```typescript
506
+ function calculateMajorLuck<T>(
507
+ adapter: DateAdapter<T>,
508
+ birthDateTime: T,
509
+ gender: "male" | "female",
510
+ yearPillar: string,
511
+ monthPillar: string
512
+ ): MajorLuckResult;
513
+ ```
514
+
515
+ #### `analyzeYongShen(year, month, day, hour)`
516
+
517
+ 억부와 조후를 고려하여 용신과 희신을 추출합니다.
518
+
519
+ ```typescript
520
+ function analyzeYongShen(
521
+ year: string,
522
+ month: string,
523
+ day: string,
524
+ hour: string
525
+ ): YongShenResult;
526
+ ```
527
+
528
+ #### `analyzeSolarTerms(adapter, datetime)`
529
+
530
+ 현재 및 다음 절기 정보와 경과일을 계산합니다.
531
+
532
+ ```typescript
533
+ function analyzeSolarTerms<T>(
534
+ adapter: DateAdapter<T>,
535
+ dtLocal: T
536
+ ): SolarTermInfo;
537
+ ```
538
+
539
+ **반환값:**
540
+ ```typescript
541
+ {
542
+ current: { name: "소한", hanja: "小寒", longitude: 285 },
543
+ currentDate: { year: 2024, month: 1, day: 6, hour: 5, minute: 30 },
544
+ daysSinceCurrent: 5,
545
+ next: { name: "대한", hanja: "大寒", longitude: 300 },
546
+ nextDate: { year: 2024, month: 1, day: 20, hour: 12, minute: 15 },
547
+ daysUntilNext: 10
548
+ }
549
+ ```
550
+
551
+ #### `getSolarTermsForYear(adapter, year, timezone)`
552
+
553
+ 특정 연도의 24절기 날짜를 모두 계산합니다.
554
+
555
+ ```typescript
556
+ function getSolarTermsForYear<T>(
557
+ adapter: DateAdapter<T>,
558
+ year: number,
559
+ timezone: string
560
+ ): Array<{ term: SolarTerm; date: {...} }>;
561
+ ```
562
+
428
563
  ## 고급 사용법
429
564
 
430
565
  ### 태양시 보정
@@ -499,6 +634,85 @@ const result = getFourPillars(adapter, dt, {
499
634
 
500
635
  ## 예제
501
636
 
637
+ ### 대운과 세운 계산
638
+
639
+ ```typescript
640
+ const saju = getSaju(adapter, dt, {
641
+ longitudeDeg: 126.9778,
642
+ gender: "female",
643
+ yearlyLuckRange: { from: 2024, to: 2030 }
644
+ });
645
+
646
+ // 대운 확인
647
+ console.log(saju.majorLuck.pillars); // 대운 목록
648
+ console.log(saju.majorLuck.startAge); // 대운 시작 나이
649
+
650
+ // 세운 확인
651
+ saju.yearlyLuck.forEach(luck => {
652
+ console.log(`${luck.year}년(${luck.pillar}): ${luck.age}세`);
653
+ });
654
+ ```
655
+
656
+ ### 절기 정보 확인
657
+
658
+ ```typescript
659
+ const saju = getSaju(adapter, dt, {
660
+ longitudeDeg: 126.9778,
661
+ gender: "male",
662
+ });
663
+
664
+ // 현재 절기
665
+ console.log(saju.solarTerms.current.name); // "소한"
666
+ console.log(saju.solarTerms.current.hanja); // "小寒"
667
+ console.log(saju.solarTerms.daysSinceCurrent); // 5 (절기 경과일)
668
+
669
+ // 다음 절기
670
+ console.log(saju.solarTerms.next.name); // "대한"
671
+ console.log(saju.solarTerms.daysUntilNext); // 10 (다음 절기까지 남은 일)
672
+
673
+ // 절기 시작 날짜
674
+ console.log(saju.solarTerms.currentDate); // { year: 2024, month: 1, day: 6, ... }
675
+ console.log(saju.solarTerms.nextDate); // { year: 2024, month: 1, day: 20, ... }
676
+ ```
677
+
678
+ ### 십신 및 오행 분석
679
+
680
+ ```typescript
681
+ import { analyzeTenGods, countElements } from "@gracefullight/saju";
682
+
683
+ const tenGods = analyzeTenGods("己卯", "丙子", "辛巳", "戊戌");
684
+ console.log(tenGods.dayMaster); // "辛"
685
+
686
+ const elements = countElements(tenGods);
687
+ console.log(elements); // { wood: 1, fire: 1, earth: 3, metal: 1, water: 2 }
688
+ ```
689
+
690
+ ### 신강약 및 용신 분석
691
+
692
+ ```typescript
693
+ import { analyzeStrength, analyzeYongShen, getElementRecommendations } from "@gracefullight/saju";
694
+
695
+ const strength = analyzeStrength("己卯", "丙子", "辛巳", "戊戌");
696
+ console.log(strength.level); // "신약"
697
+
698
+ const yongShen = analyzeYongShen("己卯", "丙子", "辛巳", "戊戌");
699
+ console.log(yongShen.primary); // 용신 오행 (예: "earth")
700
+
701
+ const tips = getElementRecommendations(yongShen);
702
+ console.log(tips.colors); // 행운의 색상
703
+ ```
704
+
705
+ ### 합충형파해 분석
706
+
707
+ ```typescript
708
+ import { analyzeRelations } from "@gracefullight/saju";
709
+
710
+ const relations = analyzeRelations("己卯", "丙子", "辛巳", "戊戌");
711
+ relations.clashes.forEach(c => {
712
+ console.log(`${c.positions[0]}-${c.positions[1]} 지지 충: ${c.pair[0]}-${c.pair[1]}`);
713
+ });
714
+ ```
715
+
502
716
  ### 다양한 타임존에서 계산
503
717
 
504
718
  ```typescript
@@ -606,7 +820,15 @@ packages/saju/
606
820
  │ │ ├── luxon.ts # Luxon 어댑터
607
821
  │ │ └── date-fns.ts # date-fns 어댑터
608
822
  │ ├── core/ # 핵심 계산 로직
609
- │ │ └── four-pillars.ts # 메인 알고리즘
823
+ │ │ ├── four-pillars.ts # 사주 팔자 계산
824
+ │ │ ├── ten-gods.ts # 십신 분석
825
+ │ │ ├── strength.ts # 신강/신약 판정
826
+ │ │ ├── relations.ts # 합충형파해 분석
827
+ │ │ ├── luck.ts # 대운/세운 계산
828
+ │ │ ├── yongshen.ts # 용신 추출
829
+ │ │ ├── solar-terms.ts # 절기 계산
830
+ │ │ └── lunar.ts # 음력 변환
831
+ │ ├── types/ # 타입 정의
610
832
  │ ├── __tests__/ # 테스트 스위트
611
833
  │ └── index.ts # 공개 API
612
834
  ├── dist/ # 컴파일된 출력
@@ -723,7 +945,3 @@ MIT © [gracefullight](https://github.com/gracefullight)
723
945
  - [문서](https://github.com/gracefullight/saju#readme)
724
946
  - [이슈 트래커](https://github.com/gracefullight/saju/issues)
725
947
  - [토론](https://github.com/gracefullight/saju/discussions)
726
-
727
- ---
728
-
729
- Made by [gracefullight](https://github.com/gracefullight)
@@ -1,5 +1,5 @@
1
1
  import { beforeAll, describe, expect, it } from "vitest";
2
- import { createDateFnsAdapter } from "@/adapters/date-fns";
2
+ import { createDateFnsAdapter } from "../adapters/date-fns";
3
3
  describe("date-fns Adapter", () => {
4
4
  let adapter;
5
5
  beforeAll(async () => {