saju8z 1.0.0 → 1.2.0

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 (45) hide show
  1. package/README.md +405 -108
  2. package/bin/saju8z.js +160 -0
  3. package/dist/core.cjs +168 -37
  4. package/dist/core.js +168 -37
  5. package/dist/format.cjs +234 -55
  6. package/dist/format.js +234 -55
  7. package/dist/index.cjs +579 -328
  8. package/dist/index.js +579 -328
  9. package/dist/lunar.cjs +4 -4
  10. package/dist/lunar.js +4 -4
  11. package/dist/types/application/calculateSajuChart.d.ts +7 -1
  12. package/dist/types/application/normalizeDateTime.d.ts +7 -0
  13. package/dist/types/calendar/dateMath.d.ts +2 -1
  14. package/dist/types/calendar/solarTerms.d.ts +1 -0
  15. package/dist/types/config/saju8z.d.ts +1 -1
  16. package/dist/types/contracts/sajuChart.d.ts +21 -4
  17. package/dist/types/format.d.ts +1 -1
  18. package/dist/types/index.d.ts +1 -1
  19. package/dist/types/input/parseSajuChartInput.d.ts +10 -0
  20. package/dist/types/output/chartPresentation.d.ts +14 -0
  21. package/dist/types/output/createSajuPrompt.d.ts +1 -0
  22. package/dist/types/output/formatSajuChart.d.ts +1 -1
  23. package/dist/types/output/formatSajuText.d.ts +2 -0
  24. package/dist/types/saju/calculateDayPillar.d.ts +1 -0
  25. package/dist/types/saju/calculateMonthPillar.d.ts +1 -0
  26. package/dist/types/saju/calculateTenGods.d.ts +1 -0
  27. package/dist/types/saju/calculateThreePillars.d.ts +3 -0
  28. package/dist/types-cjs/application/calculateSajuChart.d.ts +7 -1
  29. package/dist/types-cjs/application/normalizeDateTime.d.ts +7 -0
  30. package/dist/types-cjs/calendar/dateMath.d.ts +2 -1
  31. package/dist/types-cjs/calendar/solarTerms.d.ts +1 -0
  32. package/dist/types-cjs/config/saju8z.d.ts +1 -1
  33. package/dist/types-cjs/contracts/sajuChart.d.ts +21 -4
  34. package/dist/types-cjs/format.d.ts +1 -1
  35. package/dist/types-cjs/index.d.ts +1 -1
  36. package/dist/types-cjs/input/parseSajuChartInput.d.ts +10 -0
  37. package/dist/types-cjs/output/chartPresentation.d.ts +14 -0
  38. package/dist/types-cjs/output/createSajuPrompt.d.ts +1 -0
  39. package/dist/types-cjs/output/formatSajuChart.d.ts +1 -1
  40. package/dist/types-cjs/output/formatSajuText.d.ts +2 -0
  41. package/dist/types-cjs/saju/calculateDayPillar.d.ts +1 -0
  42. package/dist/types-cjs/saju/calculateMonthPillar.d.ts +1 -0
  43. package/dist/types-cjs/saju/calculateTenGods.d.ts +1 -0
  44. package/dist/types-cjs/saju/calculateThreePillars.d.ts +3 -0
  45. package/package.json +5 -1
package/README.md CHANGED
@@ -1,27 +1,361 @@
1
1
  # saju8z
2
2
 
3
- 브라우저와 Node.js에서 생년월일시를 사주팔자로 변환하는 오프라인 만세력 계산 라이브러리입니다. 양력·한국 음력·윤달을 지원하며, 사주팔자와 십성 계산 결과를 객체·텍스트·JSON으로 사용할 수 있습니다.
3
+ 생년월일시로 사주팔자와 십성을 계산하고, 시간을 모르면 삼주(년·월·일)를 제공하는 만세력 CLI 라이브러리입니다.
4
4
 
5
- - TypeScript 타입 선언과 ESM·CommonJS 빌드 제공
6
- - 네트워크·API 키·데이터베이스 없이 실행
7
- - 현재 시각과 실행 환경의 시간대에 의존하지 않는 계산
8
- - 음력 변환 의존성을 번들에 포함하여 별도 런타임 의존성 설치 불필요
5
+ 양력/음력/윤달을 지원하고, 결과를 텍스트/JSON/AI 전달용 프롬프트로 출력합니다.
9
6
 
10
- Node.js에서는 22 이상을 사용합니다. 브라우저에서는 ES2022를 지원하는 환경과 ESM 번들러를 사용할 수 있습니다.
7
+ **Node.js 22 이상과 npm**이 필요합니다. 터미널에서 바로 사용하려면 `--date`·`--time` 또는 `--dt`를 본인의 생년월일시로 바꾸세요.
11
8
 
12
- ## 설치
13
9
 
14
- 사용할 프로젝트에서 npm 패키지를 설치합니다.
10
+
11
+ ## CLI 빠른 시작
12
+
13
+ ### 바로 실행하고 결과 보기
14
+
15
+ 전역 설치 없이 한 줄로 실행합니다. 아래 예시는 양력 2000년 2월 23일 00시 10분, 현재 GMT 기준입니다.
16
+
17
+ ```sh
18
+ npx --yes saju8z --date 2000-02-25 --time 04:10
19
+ ```
20
+
21
+ ### 전역 설치 후 실행
22
+
23
+ ```sh
24
+ npm install -g saju8z
25
+ saju8z --date 2000-02-25 --time 04:10
26
+ ```
27
+
28
+
29
+
30
+ ### 인자 없이 실행하고 날짜·시각 입력하기
31
+
32
+ 옵션 없이 `saju8z`를 실행하면 생년월일과 출생 시각을 차례로 질문합니다. 아래처럼 값을 입력한 뒤 각각 Enter를 누르세요.
33
+
34
+ ```sh
35
+ saju8z
36
+ ```
37
+
38
+ 입력 예시:
39
+
40
+ ```text
41
+ 생년월일과 출생 시각을 입력하세요. 양력·현재 GMT 시차로 계산합니다.
42
+ 생년월일 (YYYY-MM-DD, 예: 1998-03-05): 1998-03-05
43
+ 출생 시각 (HH:mm, 예: 11:00 / 시간을 모르면 비워두고 Enter): 11:00
44
+
45
+ [만세력]
46
+ ...
47
+ ```
48
+
49
+ - 날짜는 `1998-03-05`처럼 연도 4자리·월 2자리·일 2자리를 하이픈으로 구분합니다.
50
+ - 시각은 `11:00`처럼 24시간제의 시·분을 콜론으로 구분합니다. 오후 11시는 `23:00`, 자정은 `00:00`입니다.
51
+ - 시간을 모르면 시각 질문에서 아무것도 적지 않고 Enter를 누르세요. 삼주만 출력합니다.
52
+ - 시간을 입력하면 **양력·실행 환경의 현재 GMT 시차·기본 텍스트 형식**으로 사주를 출력합니다. 시간을 생략하면 양력 날짜 기준으로 계산하며 GMT 환산과 -30분 보정은 생략합니다.
53
+ - 잘못된 날짜·시각이나 빈 날짜는 오류로 종료합니다. 빈 시각은 시간 미상으로 처리합니다. 다시 실행해 입력하세요. 음력·윤달·고정 시차·다른 출력 형식은 아래 CLI 옵션을 사용하세요.
54
+
55
+ 대화형 입력은 **인자가 전혀 없을 때만** 시작합니다. 옵션을 전달하면 `--date` 또는 `--dt`가 필요하며, `--time`은 선택입니다. 입력 안내는 표준 오류(stderr), 계산 결과는 표준 출력(stdout)에 기록합니다.
56
+
57
+ ### 날짜와 시각을 한 번에 입력하기
58
+
59
+ `--dt`는 날짜만 적는 **`YYYYMMDD` 8자리**와 시각까지 적는 **`YYYYMMDDHHmm` 12자리**를 지원합니다. `19980305`는 `--date 1998-03-05`와 같으며 삼주를 출력합니다. `199803051100`은 `--date 1998-03-05 --time 11:00`과 같은 사주를 출력합니다.
60
+
61
+ ```sh
62
+ saju8z --dt 19980305
63
+ saju8z --dt 199803051100
64
+ saju8z --dt 199803051100 --gmt +09:00 --format json
65
+ saju8z --dt=199803051100 --gmt +09:00 --format prompt
66
+ ```
67
+
68
+ **옵션으로 실행할 때는 `--date` 또는 `--dt`를 입력해야 합니다. `--time`은 선택입니다.** `--dt`와 `--date`·`--time`을 혼용하면 오류가 발생합니다. 월·일·시·분은 각각 두 자리로 입력하며, 날짜와 시각의 유효성 검사는 기존 입력 방식과 같습니다. 시간이 있으면 `--gmt` 생략 시 현재 시차를 사용합니다. 시간이 없으면 시차 환산을 생략합니다. `--calendar lunar`·`--leap`는 두 방식 모두 사용할 수 있습니다.
69
+
70
+ ### 시간을 모를 때 삼주 출력
71
+
72
+ ```sh
73
+ saju8z --date 1998-03-05
74
+ saju8z --dt 19980305
75
+ ```
76
+
77
+ 위 두 명령은 동일한 삼주 결과를 반환합니다.
78
+
79
+ ```text
80
+
81
+ [만세력]
82
+ 양력 날짜: 1998-03-05
83
+ 출생 시각: 미상 (삼주만 제공하며 시주는 추정하거나 해석하지 않습니다.)
84
+ 시간 미상으로 GMT 환산과 -30분 보정은 적용하지 않았습니다.
85
+ 일간: 신금(辛金)
86
+
87
+ 년주: 무인(戊寅)
88
+ - 천간: 무(戊), 토(土), 정인
89
+ - 지지: 인(寅), 목(木), 정재
90
+
91
+ 월주: 갑인(甲寅)
92
+ - 천간: 갑(甲), 목(木), 정재
93
+ - 지지: 인(寅), 목(木), 정재
94
+
95
+ 일주: 신해(辛亥)
96
+ - 천간: 신(辛), 금(金), 본원
97
+ - 지지: 해(亥), 수(水), 상관
98
+ ```
99
+
100
+ 시각이 없으면 입력 날짜를 그대로 사용합니다. 음력 입력은 양력으로 변환한 날짜를 사용하며, GMT 환산과 -30분 보정은 적용하지 않습니다. 입춘·절입 당일부터 새 년주·월주를 적용합니다. 이 기준은 출생 시각을 추정한 결과가 아닙니다.
15
101
 
16
102
  ```sh
17
- npm install saju8z
103
+ saju8z --dt 19980305 --format json
104
+ ```
105
+
106
+ <details>
107
+ <summary>시간 미상 JSON 결과 펼치기</summary>
108
+
109
+ ```json
110
+ {
111
+ "normalizedDateTime": {
112
+ "year": 1998,
113
+ "month": 3,
114
+ "day": 5,
115
+ "hour": null,
116
+ "minute": null
117
+ },
118
+ "calculationDateTime": {
119
+ "year": 1998,
120
+ "month": 3,
121
+ "day": 5,
122
+ "hour": null,
123
+ "minute": null
124
+ },
125
+ "fourPillars": {
126
+ "year": {
127
+ "stem": "무",
128
+ "branch": "인"
129
+ },
130
+ "month": {
131
+ "stem": "갑",
132
+ "branch": "인"
133
+ },
134
+ "day": {
135
+ "stem": "신",
136
+ "branch": "해"
137
+ },
138
+ "hour": null
139
+ },
140
+ "tenGods": {
141
+ "yearStem": "정인",
142
+ "yearBranch": "정재",
143
+ "monthStem": "정재",
144
+ "monthBranch": "정재",
145
+ "dayBranch": "상관",
146
+ "hourStem": null,
147
+ "hourBranch": null
148
+ }
149
+ }
150
+ ```
151
+
152
+ </details>
153
+
154
+ 시간 미상 결과는 `fourPillars.hour`, `tenGods.hourStem`, `tenGods.hourBranch`가 `null`이며, `normalizedDateTime`·`calculationDateTime`의 `hour`·`minute`도 `null`입니다. 두 날짜 객체는 같은 양력 날짜를 담습니다. 텍스트·프롬프트에는 년주·월주·일주만 표시하고, 프롬프트에는 시주를 추정하거나 해석하지 않도록 안내합니다.
155
+
156
+ ### 출력 형식 선택
157
+
158
+
159
+ | 옵션 | 결과 |
160
+ | ----------------- | ------------------------ |
161
+ | `--format text` | 만세력 텍스트 (기본값) |
162
+ | `--format json` | 환산·계산 시각, 사주팔자, 십성의 JSON |
163
+ | `--format prompt` | AI 전달용 프롬프트 텍스트 |
164
+
165
+
166
+
167
+
168
+ ### 만세력 텍스트 출력:
169
+
170
+ ```text
171
+ 2000-02-25 04:10
18
172
  ```
19
173
 
20
- 설치 후 `saju8z`에서 함수를 가져와 바로 사용할 수 있습니다. 패키지 사용을 위해 이 저장소를 내려받거나 직접 빌드할 필요는 없습니다.
21
174
 
22
- ## 빠른 시작
23
175
 
24
- Node.js ESM, TypeScript, 브라우저 번들러 환경에서 동일하게 사용합니다.
176
+ &nbsp;
177
+
178
+ ```text
179
+
180
+ [만세력]
181
+ 양력 환산 시각: 2000-02-25 04:10 (GMT+09:00)
182
+ -30분 보정 후 계산 시각: 2000-02-25 03:40
183
+ 일간: 계수(癸水)
184
+
185
+ 년주: 경진(庚辰)
186
+ - 천간: 경(庚), 금(金), 정인
187
+ - 지지: 진(辰), 토(土), 정관
188
+
189
+ 월주: 무인(戊寅)
190
+ - 천간: 무(戊), 토(土), 정관
191
+ - 지지: 인(寅), 목(木), 상관
192
+
193
+ 일주: 계축(癸丑)
194
+ - 천간: 계(癸), 수(水), 본원
195
+ - 지지: 축(丑), 토(土), 편관
196
+
197
+ 시주: 갑인(甲寅)
198
+ - 천간: 갑(甲), 목(木), 상관
199
+ - 지지: 인(寅), 목(木), 상관
200
+ ```
201
+
202
+
203
+
204
+ **JSON 출력:**
205
+
206
+ ```sh
207
+ npx --yes saju8z --date 2000-02-29 --time 00:10 --gmt +09:00 --format json
208
+ ```
209
+
210
+ <details class="orca-details">
211
+ <summary>실제 JSON 결과 펼치기</summary>
212
+
213
+ ```json
214
+ {
215
+ "normalizedDateTime": {
216
+ "year": 2000,
217
+ "month": 2,
218
+ "day": 29,
219
+ "hour": 0,
220
+ "minute": 10
221
+ },
222
+ "calculationDateTime": {
223
+ "year": 2000,
224
+ "month": 2,
225
+ "day": 28,
226
+ "hour": 23,
227
+ "minute": 40
228
+ },
229
+ "fourPillars": {
230
+ "year": {
231
+ "stem": "경",
232
+ "branch": "진"
233
+ },
234
+ "month": {
235
+ "stem": "무",
236
+ "branch": "인"
237
+ },
238
+ "day": {
239
+ "stem": "병",
240
+ "branch": "진"
241
+ },
242
+ "hour": {
243
+ "stem": "무",
244
+ "branch": "자"
245
+ }
246
+ },
247
+ "tenGods": {
248
+ "yearStem": "편재",
249
+ "yearBranch": "식신",
250
+ "monthStem": "식신",
251
+ "monthBranch": "편인",
252
+ "dayBranch": "식신",
253
+ "hourStem": "식신",
254
+ "hourBranch": "정관"
255
+ }
256
+ }
257
+ ```
258
+
259
+ </details>
260
+
261
+
262
+
263
+ **AI 전달용 프롬프트 출력:**
264
+
265
+ ```sh
266
+ npx --yes saju8z --date 2000-02-29 --time 00:10 --gmt +09:00 --format prompt
267
+ ```
268
+
269
+ 해석 지침 사이에 만세력 계산 결과가 들어갑니다. 생성한 출력 전체를 AI 대화창에 붙여 넣어 사용합니다.
270
+
271
+ CLI 자체는 AI를 호출하거나 해석을 생성하지 않습니다.
272
+
273
+ <details class="orca-details">
274
+ <summary>실제 프롬프트 결과 펼치기</summary>
275
+
276
+ ```text
277
+ 너는 전통 명리학의 관점으로 사주 계산 결과를 설명하는 해설자다.
278
+
279
+ 아래 만세력 계산 결과를 바탕으로 사주를 설명해 줘.
280
+ 사주팔자를 다시 계산하지 말고 제공된 정보를 사용해 줘.
281
+
282
+ [만세력]
283
+ 양력 환산 시각: 2000-02-29 00:10 (GMT+09:00)
284
+ -30분 보정 후 계산 시각: 2000-02-28 23:40
285
+ 일간: 병화(丙火)
286
+
287
+ 년주: 경진(庚辰)
288
+ - 천간: 경(庚), 금(金), 편재
289
+ - 지지: 진(辰), 토(土), 식신
290
+
291
+ 월주: 무인(戊寅)
292
+ - 천간: 무(戊), 토(土), 식신
293
+ - 지지: 인(寅), 목(木), 편인
294
+
295
+ 일주: 병진(丙辰)
296
+ - 천간: 병(丙), 화(火), 본원
297
+ - 지지: 진(辰), 토(土), 식신
298
+
299
+ 시주: 무자(戊子)
300
+ - 천간: 무(戊), 토(土), 식신
301
+ - 지지: 자(子), 수(水), 정관
302
+
303
+ 다음 내용을 설명해라.
304
+ 1. 성격적으로 나타날 수 있는 경향과 강점
305
+ 2. 스트레스를 받을 때 나타날 수 있는 반응
306
+ 3. 대인관계와 의사소통에서 참고할 점
307
+ 4. 업무 방식과 협업에서 참고할 점
308
+ 5. 스스로 확인해 볼 질문 3가지
309
+
310
+ 답변 기준:
311
+ - 전통적 상징 해석과 실제로 확인된 사실을 구분해라.
312
+ - 사주 용어를 사용하지 마라.
313
+ - 성격이나 미래를 단정하지 말고 가능한 경향으로 표현해라.
314
+ - 10살짜리도 이해할 수 있도록 쉽게 풀어서 설명해라.
315
+ - 제공되지 않은 대운·세운·지장간 등의 계산 결과를 만들어내지 마라.
316
+ - 정보가 부족한 질문에는 무엇이 더 필요한지 설명해라
317
+ ```
318
+
319
+ </details>
320
+
321
+
322
+
323
+ ### 음력과 윤달 입력
324
+
325
+ 양력은 기본값입니다. 한국 음력 날짜는 `--calendar lunar`를 추가하고, **음력 윤달이면 `--leap`도 함께** 지정합니다. 날짜와 출생 시각은 선택한 달력과 GMT 기준으로 입력합니다.
326
+
327
+ ```sh
328
+ # 음력 평달 2017년 5월 1일 12:00
329
+ npx --yes saju8z --date 2017-05-01 --time 12:00 --gmt +09:00 --calendar lunar
330
+
331
+ # 음력 윤5월 1일 12:00 → 양력 2017-06-24 12:00과 같은 계산 결과
332
+ npx --yes saju8z --date 2017-05-01 --time 12:00 --gmt +09:00 --calendar lunar --leap
333
+ ```
334
+
335
+
336
+
337
+ ### CLI 옵션과 시차
338
+
339
+
340
+ | 옵션 | 필수 | 기본값·설명 |
341
+ | -------------- | --- | ----------------------------------------------------- |
342
+ | `--dt` | 선택 | 날짜 `YYYYMMDD` 8자리 또는 날짜·시각 `YYYYMMDDHHmm` 12자리 |
343
+ | `--date` | 조건부 | 생년월일 `YYYY-MM-DD`. 옵션 실행 시 `--dt`가 없으면 필수 |
344
+ | `--time` | 아니요 | 출생 시각 `HH:mm`, `00:00`\~`23:59`. 생략하면 삼주 출력 |
345
+ | `--gmt` | 아니요 | 고정 시차 `±HH:mm`, `-12:00`\~`+14:00` 기본값은 실행 환경의 현재 GMT |
346
+ | `--calendar` | 아니요 | `solar`(기본, 양력) 또는 `lunar`(한국 음력) |
347
+ | `--leap` | 아니요 | 음력 윤달일 때 지정. `--calendar lunar`와 함께 사용 |
348
+ | `--format` | 아니요 | `text`(기본), `json`, `prompt` |
349
+ | `--help`, `-h` | 아니요 | 도움말 출력 |
350
+
351
+
352
+ 시차는 `--gmt -05:00` 또는 `--gmt=-05:00`처럼 전달합니다.
353
+
354
+ `--gmt`를 생략하면 출생일 당시가 아닌 **실행 시점의 GMT 시차**를 사용합니다. 한국 표준시 환경에서는 `+09:00`이며, 서머타임을 사용하는 환경에서는 현재 서머타임도 반영됩니다. 출생 당시 위치의 시차로 계산하려면 해당 시차를 직접 지정하세요. 시간 미상일 때는 `--gmt` 값에 관계없이 날짜 기준 삼주를 계산합니다. 전달한 GMT 값의 형식과 범위는 계속 검증합니다.
355
+
356
+
357
+
358
+ ## 라이브러리 적용
25
359
 
26
360
  ```js
27
361
  import { calculateSajuChart, formatSajuChart } from "saju8z";
@@ -34,36 +368,39 @@ const result = calculateSajuChart({
34
368
 
35
369
  console.log(result.fourPillars); // 사주팔자 객체
36
370
  console.log(result.tenGods); // 십성 객체
37
- console.log(formatSajuChart(result, "text")); // Markdown 표 문자열
371
+ console.log(formatSajuChart(result, "text")); // 만세력 텍스트 문자열
38
372
  console.log(formatSajuChart(result, "json")); // JSON 문자열
373
+ console.log(formatSajuChart(result, "prompt")); // AI 전달용 프롬프트 문자열
39
374
  ```
40
375
 
41
- CommonJS에서는 `require`로 가져옵니다.
42
376
 
43
- ```js
44
- const { calculateSajuChart, formatSajuChart } = require("saju8z");
45
377
 
46
- const result = calculateSajuChart({
47
- date: "2000-02-29",
48
- time: "00:10",
49
- gmt: "+09:00"
50
- });
51
- console.log(formatSajuChart(result));
378
+ 시간을 모르면 라이브러리에서도 `time`을 생략하거나 `undefined`로 전달합니다.
379
+
380
+ ```ts
381
+ const unknown = calculateSajuChart({ date: "1998-03-05", gmt: "+09:00" });
382
+ console.log(unknown.fourPillars.hour); // null
383
+ console.log(unknown.normalizedDateTime.hour); // null
384
+ console.log(formatSajuChart(unknown)); // 년·월·일 삼주
52
385
  ```
53
386
 
387
+ 시간을 명시한 호출은 `SajuChartResultWithTime`, 생략한 호출은 `SajuChartResultWithoutTime`으로 추론됩니다. `SajuChartResult`는 두 결과의 유니온입니다. `time`이 선택적인 `SajuChartInput` 변수를 전달하면 결과도 유니온이므로 시주를 사용하기 전에 `null`을 확인하세요. 두 결과 타입은 `saju8z`와 `saju8z/format`에서 가져올 수 있습니다. 저수준 `saju8z/core`의 기존 사주 타입과 함수는 그대로 사용합니다.
388
+
54
389
  ## 입력
55
390
 
56
391
  `calculateSajuChart(input)`은 다음 객체를 받습니다.
57
392
 
58
- | 필드 | 타입 | 필수 | 설명 |
59
- | ----------- | --------- | -------- | ------------------------------------------------------ | ------------------------------------- |
60
- | `date` | `string` | 예 | `YYYY-MM-DD`. 선택한 달력 기준의 날짜 |
61
- | `time` | `string` | 예 | `HH:mm`, `00:00`\~`23:59`. 초는 지원하지 않음 |
62
- | `gmt` | `string` | 예 | 부호를 포함한 고정 시차 `±HH:mm`, `-12:00`\~`+14:00` |
63
- | `calendar` | `"solar" | "lunar"` | 아니요 | 양력 또는 한국 음력. 기본값 `"solar"` |
64
- | `leapMonth` | `boolean` | 아니요 | 음력 윤달 여부. 기본값 `false`, 음력에서만 `true` 허용 |
65
393
 
66
- GMT는 출생 당시 날짜·시간의 시차를 직접 지정합니다. 예를 들어 한국 표준시는 `+09:00`, UTC는 `+00:00`입니다. 실행 환경의 시간대나 지역 이름으로 자동 추정하지 않습니다.
394
+ | 필드 | 타입 | 필수 | 설명 |
395
+ | ----------- | -------------------- | --- | ------------------------------------------ |
396
+ | `date` | `string` | 예 | `YYYY-MM-DD`. 선택한 달력 기준의 날짜 |
397
+ | `time` | `string` | 아니요 | `HH:mm`, `00:00`\~`23:59`. 생략 또는 `undefined`이면 시간 미상 |
398
+ | `gmt` | `string` | 예 | 부호를 포함한 고정 시차 `±HH:mm`, `-12:00`\~`+14:00` |
399
+ | `calendar` | `"solar"`, `"lunar"` | 아니요 | 양력 또는 한국 음력. 기본값 `"solar"` |
400
+ | `leapMonth` | `boolean` | 아니요 | 음력 윤달 여부. 기본값 `false`, 음력에서만 `true` 허용 |
401
+
402
+
403
+ 라이브러리 API의 `gmt`는 출생 당시 날짜·시간의 시차를 직접 지정합니다. 예를 들어 한국 표준시는 `+09:00`, UTC는 `+00:00`입니다. 실행 환경의 시간대나 지역 이름으로 자동 추정하지 않습니다. `gmt`는 시간 미상 입력에서도 필수이며 형식을 검증하지만, 날짜 기준 계산에는 사용하지 않습니다. `time: ""`·`time: null`은 허용하지 않습니다. CLI에서도 `--time` 값을 비우는 대신 옵션을 생략하고, 대화형 질문에서만 빈 시각을 허용합니다.
67
404
 
68
405
  음력 윤달은 다음과 같이 입력합니다.
69
406
 
@@ -78,113 +415,73 @@ const result = calculateSajuChart({
78
415
  // 양력 2017-06-24 12:00, GMT+09:00 입력과 같은 결과
79
416
  ```
80
417
 
81
- ## 결과와 출력 형식
82
-
83
- `calculateSajuChart`는 JSON으로 직렬화 가능한 `SajuChartResult` 객체를 반환합니다.
84
418
 
85
- | 필드 | 내용 |
86
- | --------------------- | ----------------------------------------------------------------------------------------------------------- |
87
- | `normalizedDateTime` | 양력으로 변환하고 GMT+09:00으로 환산한 `{ year, month, day, hour, minute }` |
88
- | `calculationDateTime` | 환산 시각에 -30분 보정을 적용한 계산 시각 |
89
- | `fourPillars` | `year`, `month`, `day`, `hour`의 사주팔자. 각 값은 `{ stem, branch }` |
90
- | `tenGods` | 일간 기준 십성. `yearStem`, `yearBranch`, `monthStem`, `monthBranch`, `dayBranch`, `hourStem`, `hourBranch` |
91
- | `calculationProfile` | 계산 규칙 식별자. 현재 `saju8z-fixed-gmt-kst-minus30-v1` |
92
419
 
93
- 천간·지지·십성은 `"병"`, `"진"`, `"식신"`과 같은 한국어 문자열입니다. 일간 자체의 십성 필드는 없으며, 텍스트 표에서는 `본원`으로 표시합니다.
420
+ ## 결과와 출력 형식
94
421
 
95
- ### 텍스트
422
+ `calculateSajuChart`는 JSON으로 직렬화 가능한 `SajuChartResult` 객체를 반환합니다.
96
423
 
97
- `formatSajuChart(result)` 또는 `formatSajuChart(result, "text")`는 시주·일주·월주·년주 순서의 Markdown 표를 반환합니다. 천간·지지의 한자, 오행, 십성을 포함합니다. 빠른 시작 예제의 출력은 다음과 같습니다.
98
424
 
99
- ```text
100
- | 구분 | 시주 | 일주 | 월주 | 년주 |
101
- | --- | --- | --- | --- | --- |
102
- | 천간 | 무(戊) | 병(丙) | 무(戊) | 경(庚) |
103
- | 천간 오행 | 土 | 火 | 土 | 金 |
104
- | 천간 십성 | 식신 | 본원 | 식신 | 편재 |
105
- | 지지 | 자(子) | 진(辰) | 인(寅) | 진(辰) |
106
- | 지지 오행 | 水 | 土 | 木 | 土 |
107
- | 지지 십성 | 정관 | 식신 | 편인 | 식신 |
108
- ```
425
+ | 필드 | 내용 |
426
+ | --------------------- | ----------------------------------------------------------------------------------------------------- |
427
+ | `normalizedDateTime` | 시간이 있으면 GMT+09:00으로 환산한 양력 시각. 시간이 없으면 양력 날짜와 `hour: null`, `minute: null` |
428
+ | `calculationDateTime` | 시간이 있으면 -30분 보정한 시각. 시간이 없으면 `normalizedDateTime`과 동일한 날짜·null 시각 |
429
+ | `fourPillars` | `year`, `month`, `day`, `hour`의 사주팔자. 시간이 없으면 `hour: null` |
430
+ | `tenGods` | 일간 기준 십성. `yearStem`, `yearBranch`, `monthStem`, `monthBranch`, `dayBranch`, `hourStem`, `hourBranch`. 시간 미상이면 마지막 두 필드는 `null` |
109
431
 
110
- ### JSON
111
432
 
112
- `formatSajuChart(result, "json")`은 결과 객체 전체를 들여쓰기한 JSON 문자열로 반환합니다. 저장하거나 전송할 때 사용합니다. 객체가 필요하면 `calculateSajuChart`의 반환값을 바로 사용하면 됩니다.
433
+ 천간·지지·십성은 `"병"`, `"진"`, `"식신"`과 같은 한국어 문자열입니다. 일간 자체의 십성 필드는 없으며, 만세력 텍스트에서는 `본원`으로 표시합니다.
113
434
 
114
- ```js
115
- const json = formatSajuChart(result, "json");
116
- const restored = JSON.parse(json);
117
- console.log(restored.fourPillars.day); // { stem: "병", branch: "진" }
118
- ```
119
435
 
120
- ## TypeScript와 오류 처리
121
436
 
122
- 주 진입점은 계산·출력 함수, 오류 클래스와 세 가지 타입을 제공합니다.
437
+ ## 추가 진입점
123
438
 
124
- ```ts
125
- import { calculateSajuChart, formatSajuChart, UserInputError } from "saju8z";
126
- import type { SajuChartInput, SajuChartResult, SajuChartFormat } from "saju8z";
127
439
 
128
- const input: SajuChartInput = {
129
- date: "2000-02-29",
130
- time: "00:10",
131
- gmt: "+09:00"
132
- };
133
- const format: SajuChartFormat = "json";
134
-
135
- try {
136
- const result: SajuChartResult = calculateSajuChart(input);
137
- console.log(formatSajuChart(result, format));
138
- } catch (error) {
139
- if (error instanceof UserInputError) {
140
- console.error(error.message);
141
- } else {
142
- throw error;
143
- }
144
- }
145
- ```
440
+ | 가져오기 경로 | 용도 |
441
+ | --------------- | ------------------------------------------------------------------ |
442
+ | `saju8z` | `calculateSajuChart`, `formatSajuChart`, `UserInputError` 및 입출력 타입 |
443
+ | `saju8z/core` | 저수준 계산 함수, 상수, 간지·오행 데이터와 도메인 타입 |
444
+ | `saju8z/lunar` | `lunarToSolar`, `lunarMonthDays`, `hasLunarLeapMonth` |
445
+ | `saju8z/format` | `formatSajuChart`, `SajuChartFormat`, `SajuChartResult` 타입 |
146
446
 
147
- 잘못된 날짜·시각·GMT, 지원 범위 밖 날짜, 존재하지 않는 윤달은 `UserInputError`를 발생시킵니다. 출력 형식은 `"text"`와 `"json"`만 허용합니다.
148
447
 
149
- ## 추가 진입점
448
+ 일반적인 만세력 계산에는 `saju8z`를 사용합니다. 저수준 함수는 입력 검증과 보정 적용 방식을 호출자가 확인해야 합니다.
150
449
 
151
- | 가져오기 경로 | 용도 |
152
- | --------------- | ------------------------------------------------------------------------ |
153
- | `saju8z` | `calculateSajuChart`, `formatSajuChart`, `UserInputError` 및 입출력 타입 |
154
- | `saju8z/core` | 저수준 계산 함수, 상수, 간지·오행 데이터와 도메인 타입 |
155
- | `saju8z/lunar` | `lunarToSolar`, `lunarMonthDays`, `hasLunarLeapMonth` |
156
- | `saju8z/format` | `formatSajuChart`, `SajuChartFormat`, `SajuChartResult` 타입 |
157
450
 
158
- 일반적인 만세력 계산에는 `saju8z`를 사용합니다. 저수준 함수는 입력 검증과 보정 적용 방식을 호출자가 확인해야 합니다.
159
451
 
160
452
  ## 계산 기준과 지원 범위
161
453
 
454
+ 시간을 입력한 경우 기존 계산 기준을 적용합니다.
455
+
162
456
  1. 음력이면 양력으로 변환합니다.
163
457
  2. 입력 GMT에서 GMT+09:00으로 환산합니다.
164
458
  3. -30분을 보정한 시각으로 사주팔자를 계산합니다.
165
459
 
166
- 년주는 입춘, 월주는 프로젝트의 고정 절입 시각 표, 일주는 자정을 기준으로 합니다. 고정 절입 표는 실제 연도별 천문 절기 시각과 차이가 있을 수 있습니다. 서머타임·역사적 시차·출생지 경도 보정은 자동 적용하지 않습니다.
460
+ 시간을 생략한 경우 음력 변환만 수행하고, 시차 환산과 -30분 보정 없이 해당 양력 날짜로 삼주를 계산합니다. 입춘·절입 당일부터 새 년주·월주를 적용하고 일주는 입력 날짜 기준입니다. 임의의 자정·정오를 출생 시각으로 대입하지 않습니다.
461
+
462
+ 시간을 입력한 경우 년주는 입춘, 월주는 프로젝트의 고정 절입 시각 표, 일주는 자정을 기준으로 합니다. 고정 절입 표는 실제 연도별 천문 절기 시각과 차이가 있을 수 있습니다. 서머타임·역사적 시차·출생지 경도 보정은 자동 적용하지 않습니다.
167
463
 
168
- 양력 입력과 GMT+09:00 환산 날짜는 1900~2100년을 지원합니다. 음력은 1900년부터 음력 2050년 11월 18일까지의 유효 날짜를 지원합니다. -30분 보정으로 1900년 첫날이 전년 말로 이동할 수 있습니다.
464
+ 양력 입력과 GMT+09:00 환산 날짜는 1900~2100년을 지원합니다. 음력은 1900년부터 음력 2050년 11월 18일까지의 유효 날짜를 지원합니다. 시간을 입력하면 -30분 보정으로 1900년 첫날이 전년 말로 이동할 수 있습니다. 시간이 없으면 해당 날짜를 보존합니다.
169
465
 
170
466
  성별 입력은 필요하지 않습니다. 대운·세운·운세·성격 해석 기능은 제공하지 않습니다.
171
467
 
172
- ## 소스 개발과 패키지 검증
173
468
 
174
- 라이브러리 자체를 수정하는 경우 저장소를 내려받은 뒤 아래 명령을 사용합니다.
175
469
 
176
- ```sh
177
- npm ci
178
- npm run build # ESM·CommonJS 번들과 타입 선언 생성
179
- npm test # 빌드 후 계산·출력 테스트
180
- npm run lint
181
- npm run typecheck
182
- npm pack --dry-run # 배포 파일 목록 확인
183
- npm run test:package # tarball 설치 후 ESM/CJS·타입·브라우저·시간대 검증
184
- npm pack # saju8z-1.0.0.tgz 생성
185
- ```
470
+ ## 폴더 역할
471
+
472
+
473
+ | 위치 | 역할 |
474
+ | -------------------------- | ----------------------------- |
475
+ | `src/input/` | 입력 문자열 해석, 형식 검증, 사용자 입력 오류 |
476
+ | `src/application/` | 음력·시차 환산과 사주 계산 순서 조합 |
477
+ | `src/calendar/` | 날짜 산술, 음력 변환, 절기·태양시 보정 |
478
+ | `src/saju/`, `src/domain/` | 사주·십성 계산 규칙, 타입과 기준 데이터 |
479
+ | `src/output/` | 만세력 텍스트 생성, 프롬프트 조립과 출력 형식 선택 |
480
+ | `bin/` | CLI 옵션 해석과 표준 입출력 |
481
+ | `test/`, `scripts/` | 회귀 테스트, 빌드와 설치 패키지 검증 |
482
+
483
+
186
484
 
187
- 계산 원본은 `src/`, 테스트는 `test/`, 빌드·패키지 검증 스크립트는 `scripts/`에 있습니다. JavaScript 스크립트는 `package.json`의 `"type": "module"` 설정에 따라 ES 모듈로 실행합니다. `dist/`는 빌드 산출물이며 npm 패키지에는 실행 번들·타입 선언·README·LICENSE·제3자 고지를 포함합니다.
188
485
 
189
486
  ## 라이선스
190
487
 
@@ -192,4 +489,4 @@ npm pack # saju8z-1.0.0.tgz 생성
192
489
 
193
490
  상업적 사용·수정·재배포를 허용하며, 소프트웨어의 복사본이나 주요 부분에 저작권 및 라이선스 고지를 유지해야 합니다. 소프트웨어는 보증 없이 제공됩니다. 정확한 조건은 LICENSE 전문을 참고하세요.
194
491
 
195
- 번들에 포함된 `korean-lunar-calendar`의 원 저작권 및 MIT 라이선스 고지는 [THIRD-PARTY-LICENSES.txt](THIRD-PARTY-LICENSES.txt)에 별도로 보존합니다.
492
+ 번들에 포함된 `korean-lunar-calendar`의 원 저작권 및 MIT 라이선스 고지는 [THIRD-PARTY-LICENSES.txt](THIRD-PARTY-LICENSES.txt)에 별도로 보존합니다.