@gracefullight/saju 0.1.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.
package/README.md ADDED
@@ -0,0 +1,665 @@
1
+ # @gracefullight/saju
2
+
3
+ > 유연한 날짜 어댑터를 지원하는 사주(四柱命理) 계산 TypeScript 라이브러리
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@gracefullight/saju.svg)](https://www.npmjs.com/package/@gracefullight/saju)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **한국어** | [English](./README.en.md)
9
+
10
+ ## 주요 기능
11
+
12
+ - **정확한 사주 계산** - 천문학적 정밀도로 전통 중국 역법 알고리즘 구현
13
+ - **유연한 날짜 어댑터 패턴** - Luxon, date-fns 또는 원하는 날짜 라이브러리 사용 가능
14
+ - **타임존 & 위치 지원** - 타임존 및 지리적 좌표 적절히 처리
15
+ - **태양시 보정** - 경도 기반 평균 태양시 조정 옵션
16
+ - **트리쉐이킹 지원** - 필요한 것만 import
17
+ - **완전한 타입 지원** - TypeScript 정의 완비
18
+ - **충분한 테스트** - 85개 이상 테스트, 91% 이상 커버리지
19
+
20
+ ## 사주(四柱)란?
21
+
22
+ 사주(四柱), 또는 사주명리는 출생 연월일시를 기반으로 한 전통 한국/중국 운명 분석 시스템입니다. 각 기둥은 다음으로 구성됩니다:
23
+ - **천간(天干)**: 10개 원소 (甲乙丙丁戊己庚辛壬癸)
24
+ - **지지(地支)**: 12지지 (子丑寅卯辰巳午未申酉戌亥)
25
+
26
+ 이 라이브러리는 다음을 사용하여 기둥을 계산합니다:
27
+ - **입춘(立春)** 을 이용한 연주 전환
28
+ - **태양 황경** 을 이용한 월주 결정
29
+ - **율리우스 적일** 을 이용한 일주 계산
30
+ - **전통 중국 시진(時辰) 체계** 를 이용한 시주
31
+
32
+ ## 설치
33
+
34
+ ```bash
35
+ # pnpm 사용
36
+ pnpm add @gracefullight/saju
37
+
38
+ # npm 사용
39
+ npm install @gracefullight/saju
40
+
41
+ # yarn 사용
42
+ yarn add @gracefullight/saju
43
+ ```
44
+
45
+ ### 날짜 라이브러리 어댑터
46
+
47
+ 선호도에 따라 선택:
48
+
49
+ ```bash
50
+ # 옵션 1: Luxon (현대적인 앱에 권장)
51
+ pnpm add luxon @types/luxon
52
+
53
+ # 옵션 2: date-fns (가벼운 대안)
54
+ pnpm add date-fns date-fns-tz
55
+ ```
56
+
57
+ ## 빠른 시작
58
+
59
+ ```typescript
60
+ import { DateTime } from "luxon";
61
+ import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
62
+ import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
63
+
64
+ const adapter = await createLuxonAdapter();
65
+
66
+ const birthDateTime = DateTime.fromObject(
67
+ { year: 2000, month: 1, day: 1, hour: 18, minute: 0 },
68
+ { zone: "Asia/Seoul" }
69
+ );
70
+
71
+ const result = getFourPillars(adapter, birthDateTime, {
72
+ longitudeDeg: 126.9778, // 서울 경도
73
+ preset: STANDARD_PRESET,
74
+ });
75
+
76
+ console.log(result);
77
+ // {
78
+ // year: "己卯", // 연주 (천간 + 지지)
79
+ // month: "丙子", // 월주
80
+ // day: "庚辰", // 일주
81
+ // hour: "辛酉", // 시주
82
+ // meta: {
83
+ // solarYear: 1999,
84
+ // sunLonDeg: 280.9,
85
+ // effectiveDayDate: { year: 2000, month: 1, day: 1 },
86
+ // adjustedHour: 18
87
+ // }
88
+ // }
89
+ ```
90
+
91
+ ## 사용법
92
+
93
+ ### Luxon 사용
94
+
95
+ ```typescript
96
+ import { DateTime } from "luxon";
97
+ import { createLuxonAdapter } from "@gracefullight/saju/adapters/luxon";
98
+ import { getFourPillars, STANDARD_PRESET, TRADITIONAL_PRESET } from "@gracefullight/saju";
99
+
100
+ const adapter = await createLuxonAdapter();
101
+
102
+ const dt = DateTime.fromObject(
103
+ { year: 2000, month: 1, day: 1, hour: 18, minute: 0 },
104
+ { zone: "Asia/Seoul" }
105
+ );
106
+
107
+ // 표준 프리셋: 자정(00:00) 날짜 경계, 태양시 보정 없음
108
+ const resultStandard = getFourPillars(adapter, dt, {
109
+ longitudeDeg: 126.9778,
110
+ preset: STANDARD_PRESET,
111
+ });
112
+
113
+ // 전통 프리셋: 자시(23:00) 날짜 경계, 태양시 보정 사용
114
+ const resultTraditional = getFourPillars(adapter, dt, {
115
+ longitudeDeg: 126.9778,
116
+ preset: TRADITIONAL_PRESET,
117
+ });
118
+ ```
119
+
120
+ ### date-fns 사용
121
+
122
+ ```typescript
123
+ import { createDateFnsAdapter } from "@gracefullight/saju/adapters/date-fns";
124
+ import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
125
+
126
+ const adapter = await createDateFnsAdapter();
127
+
128
+ const dt = {
129
+ date: new Date(1992, 9, 12, 19, 16), // 주의: 월은 0부터 시작
130
+ timeZone: "Asia/Seoul",
131
+ };
132
+
133
+ const result = getFourPillars(adapter, dt, {
134
+ longitudeDeg: 126.9778,
135
+ preset: STANDARD_PRESET,
136
+ });
137
+ ```
138
+
139
+ ### 커스텀 날짜 어댑터
140
+
141
+ `DateAdapter` 인터페이스를 구현하여 원하는 날짜 라이브러리 사용:
142
+
143
+ ```typescript
144
+ import type { DateAdapter } from "@gracefullight/saju";
145
+
146
+ const myAdapter: DateAdapter<MyDateType> = {
147
+ // 날짜 컴포넌트 getter
148
+ getYear: (date) => date.year,
149
+ getMonth: (date) => date.month,
150
+ getDay: (date) => date.day,
151
+ getHour: (date) => date.hour,
152
+ getMinute: (date) => date.minute,
153
+ getSecond: (date) => date.second,
154
+ getZoneName: (date) => date.zoneName,
155
+
156
+ // 날짜 연산
157
+ plusMinutes: (date, minutes) => date.add({ minutes }),
158
+ plusDays: (date, days) => date.add({ days }),
159
+ minusDays: (date, days) => date.subtract({ days }),
160
+
161
+ // 타임존 연산
162
+ toUTC: (date) => date.toUTC(),
163
+ setZone: (date, zoneName) => date.setZone(zoneName),
164
+
165
+ // 변환
166
+ toISO: (date) => date.toISO(),
167
+ toMillis: (date) => date.valueOf(),
168
+ fromMillis: (millis, zone) => MyDate.fromMillis(millis, zone),
169
+
170
+ // 유틸리티
171
+ createUTC: (year, month, day, hour, minute, second) =>
172
+ MyDate.utc(year, month, day, hour, minute, second),
173
+ isGreaterThanOrEqual: (date1, date2) => date1 >= date2,
174
+ };
175
+ ```
176
+
177
+ ## API 레퍼런스
178
+
179
+ ### 설정 프리셋
180
+
181
+ #### `STANDARD_PRESET`
182
+ 자정 날짜 경계와 태양시 보정 없는 현대적 해석
183
+
184
+ ```typescript
185
+ {
186
+ dayBoundary: "midnight", // 날짜는 00:00에 시작
187
+ useMeanSolarTimeForHour: false, // 시주는 현지 시간 사용
188
+ useMeanSolarTimeForBoundary: false // 날짜 경계는 현지 시간 사용
189
+ }
190
+ ```
191
+
192
+ #### `TRADITIONAL_PRESET`
193
+ 자시(23:00) 날짜 경계와 태양시 보정을 사용하는 전통적 해석
194
+
195
+ ```typescript
196
+ {
197
+ dayBoundary: "zi23", // 날짜는 23:00(子時)에 시작
198
+ useMeanSolarTimeForHour: true, // 시주는 태양시 사용
199
+ useMeanSolarTimeForBoundary: true // 날짜 경계는 태양시 사용
200
+ }
201
+ ```
202
+
203
+ #### 사용 중단된 별칭
204
+ - `presetA` → `STANDARD_PRESET` 사용 권장
205
+ - `presetB` → `TRADITIONAL_PRESET` 사용 권장
206
+
207
+ ### 핵심 함수
208
+
209
+ #### `getFourPillars(adapter, datetime, options)`
210
+
211
+ 네 기둥(연주, 월주, 일주, 시주) 모두 계산
212
+
213
+ ```typescript
214
+ function getFourPillars<T>(
215
+ adapter: DateAdapter<T>,
216
+ datetime: T,
217
+ options: {
218
+ longitudeDeg: number;
219
+ preset?: {
220
+ dayBoundary: "midnight" | "zi23";
221
+ useMeanSolarTimeForHour: boolean;
222
+ useMeanSolarTimeForBoundary: boolean;
223
+ };
224
+ tzOffsetHours?: number;
225
+ }
226
+ ): {
227
+ year: string;
228
+ month: string;
229
+ day: string;
230
+ hour: string;
231
+ meta: {
232
+ solarYear: number;
233
+ sunLonDeg: number;
234
+ effectiveDayDate: { year: number; month: number; day: number };
235
+ adjustedHour: number;
236
+ };
237
+ }
238
+ ```
239
+
240
+ **매개변수:**
241
+ - `adapter`: DateAdapter 인스턴스
242
+ - `datetime`: 어댑터 형식의 날짜/시간 객체
243
+ - `options`:
244
+ - `longitudeDeg`: 지리적 경도(도 단위) (예: 서울 126.9778)
245
+ - `preset`: 설정 프리셋 (`STANDARD_PRESET` 또는 `TRADITIONAL_PRESET` 사용)
246
+ - `tzOffsetHours`: 타임존 오프셋(시간 단위), 선택사항 (기본값: 9, KST)
247
+
248
+ **반환값:** 연월일시 기둥과 메타데이터를 포함한 객체
249
+
250
+ #### `yearPillar(adapter, datetime)`
251
+
252
+ 입춘(立春, 봄의 시작) 기준으로 연주만 계산
253
+
254
+ ```typescript
255
+ function yearPillar<T>(
256
+ adapter: DateAdapter<T>,
257
+ datetime: T
258
+ ): {
259
+ idx60: number;
260
+ pillar: string;
261
+ solarYear: number;
262
+ }
263
+ ```
264
+
265
+ #### `monthPillar(adapter, datetime)`
266
+
267
+ 태양 황경 기준으로 월주만 계산
268
+
269
+ ```typescript
270
+ function monthPillar<T>(
271
+ adapter: DateAdapter<T>,
272
+ datetime: T
273
+ ): {
274
+ pillar: string;
275
+ sunLonDeg: number;
276
+ }
277
+ ```
278
+
279
+ #### `dayPillarFromDate({ year, month, day })`
280
+
281
+ 율리우스 적일을 사용하여 일주만 계산
282
+
283
+ ```typescript
284
+ function dayPillarFromDate(date: {
285
+ year: number;
286
+ month: number;
287
+ day: number;
288
+ }): {
289
+ idx60: number;
290
+ pillar: string;
291
+ }
292
+ ```
293
+
294
+ #### `hourPillar(adapter, datetime, options)`
295
+
296
+ 태양시 보정 옵션과 함께 시주만 계산
297
+
298
+ ```typescript
299
+ function hourPillar<T>(
300
+ adapter: DateAdapter<T>,
301
+ datetime: T,
302
+ options?: {
303
+ longitudeDeg?: number;
304
+ tzOffsetHours?: number;
305
+ useMeanSolarTimeForHour?: boolean;
306
+ dayBoundary?: "midnight" | "zi23";
307
+ useMeanSolarTimeForBoundary?: boolean;
308
+ }
309
+ ): {
310
+ pillar: string;
311
+ adjustedDt: T;
312
+ adjustedHour: number;
313
+ }
314
+ ```
315
+
316
+ ### 상수
317
+
318
+ ```typescript
319
+ // 10 천간(天干)
320
+ export const STEMS: string[];
321
+ // ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
322
+
323
+ // 12 지지(地支)
324
+ export const BRANCHES: string[];
325
+ // ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
326
+ ```
327
+
328
+ ### 헬퍼 함수
329
+
330
+ #### `applyMeanSolarTime(adapter, dtLocal, longitudeDeg, tzOffsetHours)`
331
+
332
+ 경도 기반 평균 태양시 보정 적용
333
+
334
+ ```typescript
335
+ function applyMeanSolarTime<T>(
336
+ adapter: DateAdapter<T>,
337
+ dtLocal: T,
338
+ longitudeDeg: number,
339
+ tzOffsetHours: number
340
+ ): T
341
+ ```
342
+
343
+ #### `effectiveDayDate(adapter, dtLocal, options)`
344
+
345
+ 날짜 경계 규칙을 고려한 유효 날짜 계산
346
+
347
+ ```typescript
348
+ function effectiveDayDate<T>(
349
+ adapter: DateAdapter<T>,
350
+ dtLocal: T,
351
+ options: {
352
+ dayBoundary?: "midnight" | "zi23";
353
+ longitudeDeg?: number;
354
+ tzOffsetHours?: number;
355
+ useMeanSolarTimeForBoundary?: boolean;
356
+ }
357
+ ): {
358
+ year: number;
359
+ month: number;
360
+ day: number;
361
+ }
362
+ ```
363
+
364
+ ## 고급 사용법
365
+
366
+ ### 태양시 보정
367
+
368
+ 태양시 보정은 현지 시계 시간과 실제 태양시의 차이를 고려하여 경도에 따라 현지 시간을 조정합니다.
369
+
370
+ ```typescript
371
+ import { applyMeanSolarTime, createLuxonAdapter } from "@gracefullight/saju";
372
+ import { DateTime } from "luxon";
373
+
374
+ const adapter = await createLuxonAdapter();
375
+ const localTime = DateTime.local(2024, 1, 1, 12, 0, 0, { zone: "Asia/Seoul" });
376
+
377
+ // 서울은 경도 126.9778°E이지만 UTC+9(표준 자오선 135°E) 사용
378
+ // 이로 인해 약 32분 차이 발생
379
+ const solarTime = applyMeanSolarTime(adapter, localTime, 126.9778, 9);
380
+ console.log(solarTime.hour); // ~11.47 (11:28)
381
+ ```
382
+
383
+ ### 날짜 경계 모드
384
+
385
+ **자정 모드** (`dayBoundary: "midnight"`):
386
+ - 날짜가 00:00 현지 시간에 변경
387
+ - 더 단순하고 현대 달력과 일치
388
+ - 일반적인 사용에 적합
389
+
390
+ **자시 모드** (`dayBoundary: "zi23"`):
391
+ - 날짜가 23:00 현지 시간에 변경
392
+ - 전통 중국 시간 체계
393
+ - 자시(子時)가 자정을 걸침 (23:00-01:00)
394
+
395
+ ```typescript
396
+ const result1 = getFourPillars(adapter, dt, {
397
+ longitudeDeg: 126.9778,
398
+ preset: { ...STANDARD_PRESET, dayBoundary: "midnight" },
399
+ });
400
+
401
+ const result2 = getFourPillars(adapter, dt, {
402
+ longitudeDeg: 126.9778,
403
+ preset: { ...STANDARD_PRESET, dayBoundary: "zi23" },
404
+ });
405
+ ```
406
+
407
+ ### 커스텀 설정
408
+
409
+ 특정 요구사항에 맞게 설정 조합:
410
+
411
+ ```typescript
412
+ const customConfig = {
413
+ dayBoundary: "midnight" as const, // 현대적인 자정 경계
414
+ useMeanSolarTimeForHour: true, // 하지만 시주는 태양시 사용
415
+ useMeanSolarTimeForBoundary: false, // 날짜 경계는 현지 시간 사용
416
+ };
417
+
418
+ const result = getFourPillars(adapter, dt, {
419
+ longitudeDeg: 126.9778,
420
+ preset: customConfig,
421
+ });
422
+ ```
423
+
424
+ ## 지리적 좌표
425
+
426
+ 참고용 주요 도시 경도:
427
+
428
+ | 도시 | 경도 | 예시 |
429
+ |------|------|------|
430
+ | 서울, 대한민국 | 126.9778°E | `longitudeDeg: 126.9778` |
431
+ | 베이징, 중국 | 116.4074°E | `longitudeDeg: 116.4074` |
432
+ | 도쿄, 일본 | 139.6917°E | `longitudeDeg: 139.6917` |
433
+ | 상하이, 중국 | 121.4737°E | `longitudeDeg: 121.4737` |
434
+ | 타이베이, 대만 | 121.5654°E | `longitudeDeg: 121.5654` |
435
+
436
+ ## 예제
437
+
438
+ ### 다양한 타임존에서 계산
439
+
440
+ ```typescript
441
+ import { DateTime } from "luxon";
442
+ import { createLuxonAdapter, getFourPillars, TRADITIONAL_PRESET } from "@gracefullight/saju";
443
+
444
+ const adapter = await createLuxonAdapter();
445
+
446
+ // 뉴욕 출생 시간
447
+ const nyTime = DateTime.fromObject(
448
+ { year: 1992, month: 10, day: 12, hour: 6, minute: 16 },
449
+ { zone: "America/New_York" }
450
+ );
451
+
452
+ const result = getFourPillars(adapter, nyTime, {
453
+ longitudeDeg: -74.0060, // 뉴욕 경도
454
+ tzOffsetHours: -5, // EST 오프셋
455
+ preset: TRADITIONAL_PRESET,
456
+ });
457
+ ```
458
+
459
+ ### 개별 기둥 계산
460
+
461
+ ```typescript
462
+ import { yearPillar, monthPillar, dayPillarFromDate, hourPillar } from "@gracefullight/saju";
463
+
464
+ // 연주
465
+ const year = yearPillar(adapter, dt);
466
+ console.log(year.pillar, year.solarYear);
467
+
468
+ // 월주
469
+ const month = monthPillar(adapter, dt);
470
+ console.log(month.pillar, month.sunLonDeg);
471
+
472
+ // 일주 (어댑터 불필요)
473
+ const day = dayPillarFromDate({ year: 1992, month: 10, day: 12 });
474
+ console.log(day.pillar);
475
+
476
+ // 태양시를 사용한 시주
477
+ const hour = hourPillar(adapter, dt, {
478
+ longitudeDeg: 126.9778,
479
+ useMeanSolarTimeForHour: true,
480
+ });
481
+ console.log(hour.pillar, hour.adjustedHour);
482
+ ```
483
+
484
+ ### 일괄 처리
485
+
486
+ ```typescript
487
+ const birthDates = [
488
+ { year: 1990, month: 1, day: 15, hour: 10, minute: 30 },
489
+ { year: 1995, month: 5, day: 20, hour: 14, minute: 45 },
490
+ { year: 2000, month: 12, day: 25, hour: 18, minute: 0 },
491
+ ];
492
+
493
+ const adapter = await createLuxonAdapter();
494
+
495
+ const results = birthDates.map((birth) => {
496
+ const dt = DateTime.fromObject(birth, { zone: "Asia/Seoul" });
497
+ return {
498
+ birth,
499
+ pillars: getFourPillars(adapter, dt, {
500
+ longitudeDeg: 126.9778,
501
+ preset: STANDARD_PRESET,
502
+ }),
503
+ };
504
+ });
505
+ ```
506
+
507
+ ## 개발
508
+
509
+ ### 설정
510
+
511
+ ```bash
512
+ # 저장소 클론
513
+ git clone https://github.com/gracefullight/saju.git
514
+ cd saju
515
+
516
+ # 의존성 설치
517
+ pnpm install
518
+
519
+ # 테스트 실행
520
+ pnpm test
521
+
522
+ # 커버리지와 함께 테스트 실행
523
+ pnpm test:coverage
524
+
525
+ # 빌드
526
+ pnpm build
527
+
528
+ # 린트
529
+ pnpm lint
530
+
531
+ # 포맷
532
+ pnpm lint:fix
533
+ ```
534
+
535
+ ### 프로젝트 구조
536
+
537
+ ```
538
+ packages/saju/
539
+ ├── src/
540
+ │ ├── adapters/ # 날짜 라이브러리 어댑터
541
+ │ │ ├── date-adapter.ts # 어댑터 인터페이스
542
+ │ │ ├── luxon.ts # Luxon 어댑터
543
+ │ │ └── date-fns.ts # date-fns 어댑터
544
+ │ ├── core/ # 핵심 계산 로직
545
+ │ │ └── four-pillars.ts # 메인 알고리즘
546
+ │ ├── __tests__/ # 테스트 스위트
547
+ │ └── index.ts # 공개 API
548
+ ├── dist/ # 컴파일된 출력
549
+ ├── coverage/ # 테스트 커버리지 리포트
550
+ └── README.md
551
+ ```
552
+
553
+ ### 테스트 실행
554
+
555
+ ```bash
556
+ # 모든 테스트 실행
557
+ pnpm test
558
+
559
+ # watch 모드로 테스트 실행
560
+ pnpm test:watch
561
+
562
+ # 커버리지 리포트 생성
563
+ pnpm test:coverage
564
+ ```
565
+
566
+ 커버리지 결과:
567
+ ```
568
+ File | % Stmts | % Branch | % Funcs | % Lines
569
+ -------------------|---------|----------|---------|----------
570
+ All files | 91.45 | 80.68 | 96.55 | 91.45
571
+ src/adapters | 94.59 | 90.24 | 100 | 94.59
572
+ src/core | 96.87 | 75.55 | 100 | 96.87
573
+ ```
574
+
575
+ ## 자주 묻는 질문
576
+
577
+ ### 단일 날짜 라이브러리 대신 날짜 어댑터를 사용하는 이유는?
578
+
579
+ 프로젝트마다 다른 날짜 라이브러리를 사용합니다. 어댑터 패턴을 통해:
580
+ - 추가 의존성 없이 기존 날짜 라이브러리 사용 가능
581
+ - 필요한 것만 포함하여 번들 크기 최소화
582
+ - 프로젝트의 날짜 처리 방식과 일관성 유지
583
+
584
+ ### STANDARD_PRESET과 TRADITIONAL_PRESET의 차이는?
585
+
586
+ **STANDARD_PRESET**은 현대적 관례 사용:
587
+ - 날짜가 자정(00:00)에 시작
588
+ - 현지 시계 시간 사용
589
+ - 일반적인 사용에 더 간단
590
+
591
+ **TRADITIONAL_PRESET**은 전통 중국 점성술 따름:
592
+ - 날짜가 자시(23:00)에 시작
593
+ - 경도 기반 태양시 보정 적용
594
+ - 역사적으로 더 정확
595
+
596
+ ### 계산은 얼마나 정확한가요?
597
+
598
+ 이 라이브러리는 다음을 구현합니다:
599
+ - 일주를 위한 율리우스 적일 알고리즘 (모든 역사적 날짜에 정확)
600
+ - 월주를 위한 천문학적 태양 황경 계산
601
+ - 연주를 위한 입춘(봄의 시작) 계산
602
+ - 시주를 위한 전통 중국 시진(時辰) 체계
603
+
604
+ 모든 알고리즘은 알려진 역사적 날짜로 테스트되었으며 전통 중국 달력 참고자료와 일치합니다.
605
+
606
+ ### 역사적 날짜에도 사용할 수 있나요?
607
+
608
+ 네! 율리우스 적일 알고리즘은 다음에서 올바르게 작동합니다:
609
+ - 그레고리력의 모든 날짜 (1582년 이후)
610
+ - 율리우스력의 대부분 날짜 (적절한 달력 변환 포함)
611
+ - 먼 미래의 날짜
612
+
613
+ 다만, 약 1970년 이전 날짜의 타임존 데이터는 덜 정확할 수 있습니다.
614
+
615
+ ### 같은 출생 시간이 다른 프리셋에서 다른 결과를 주는 이유는?
616
+
617
+ 프리셋은 다음에 영향을 미칩니다:
618
+ 1. **날짜 경계**: 날짜가 실제로 변경되는 시점 (자정 vs. 23:00)
619
+ 2. **태양시**: 경도 차이에 대한 조정 여부
620
+
621
+ 예를 들어, 23:30은 다음과 같을 수 있습니다:
622
+ - 같은 날의 자시 (자정 경계 사용 시)
623
+ - 다음 날의 자시 (자시23 경계 사용 시)
624
+
625
+ 이는 의도적이며 사주 해석의 다양한 학파를 반영합니다.
626
+
627
+ ## 기여하기
628
+
629
+ 기여를 환영합니다! Pull Request를 자유롭게 제출해주세요.
630
+
631
+ 1. 저장소 포크
632
+ 2. feature 브랜치 생성 (`git checkout -b feature/amazing-feature`)
633
+ 3. 변경사항 커밋 (`git commit -m 'Add some amazing feature'`)
634
+ 4. 브랜치에 푸시 (`git push origin feature/amazing-feature`)
635
+ 5. Pull Request 오픈
636
+
637
+ ### 가이드라인
638
+
639
+ - 새 기능에 대한 테스트 작성
640
+ - 코드 커버리지 유지 또는 개선
641
+ - 기존 코드 스타일 따르기 (Biome으로 강제)
642
+ - 필요에 따라 문서 업데이트
643
+
644
+ ## 라이선스
645
+
646
+ MIT © [gracefullight](https://github.com/gracefullight)
647
+
648
+ ## 크레딧
649
+
650
+ 이 라이브러리는 사주명리(四柱命理)에 사용되는 전통 중국 역법 알고리즘과 천문 계산을 기반으로 합니다.
651
+
652
+ ## 관련 프로젝트
653
+
654
+ - [Luxon](https://moment.github.io/luxon/) - 현대적인 날짜/시간 라이브러리
655
+ - [date-fns](https://date-fns.org/) - 현대적인 JavaScript 날짜 유틸리티 라이브러리
656
+
657
+ ## 지원
658
+
659
+ - [문서](https://github.com/gracefullight/saju#readme)
660
+ - [이슈 트래커](https://github.com/gracefullight/saju/issues)
661
+ - [토론](https://github.com/gracefullight/saju/discussions)
662
+
663
+ ---
664
+
665
+ Made by [gracefullight](https://github.com/gracefullight)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=date-fns-adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-fns-adapter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/date-fns-adapter.test.ts"],"names":[],"mappings":""}