@gracefullight/saju 0.1.1 → 0.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.
- package/README.en.md +74 -10
- package/README.md +74 -10
- package/dist/__tests__/four-pillars.test.js +52 -40
- package/dist/__tests__/lunar.test.d.ts +2 -0
- package/dist/__tests__/lunar.test.d.ts.map +1 -0
- package/dist/__tests__/lunar.test.js +83 -0
- package/dist/core/four-pillars.d.ts +2 -0
- package/dist/core/four-pillars.d.ts.map +1 -1
- package/dist/core/four-pillars.js +7 -4
- package/dist/core/lunar.d.ts +13 -0
- package/dist/core/lunar.d.ts.map +1 -0
- package/dist/core/lunar.js +24 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +4 -1
package/README.en.md
CHANGED
|
@@ -77,13 +77,19 @@ console.log(result);
|
|
|
77
77
|
// {
|
|
78
78
|
// year: "己卯", // Year Pillar (Heavenly Stem + Earthly Branch)
|
|
79
79
|
// month: "丙子", // Month Pillar
|
|
80
|
-
// day: "
|
|
81
|
-
// hour: "
|
|
80
|
+
// day: "辛巳", // Day Pillar
|
|
81
|
+
// hour: "戊戌", // Hour Pillar
|
|
82
|
+
// lunar: {
|
|
83
|
+
// lunarYear: 1999,
|
|
84
|
+
// lunarMonth: 11,
|
|
85
|
+
// lunarDay: 25,
|
|
86
|
+
// isLeapMonth: false
|
|
87
|
+
// },
|
|
82
88
|
// meta: {
|
|
83
|
-
//
|
|
89
|
+
// solarYearUsed: 1999,
|
|
84
90
|
// sunLonDeg: 280.9,
|
|
85
91
|
// effectiveDayDate: { year: 2000, month: 1, day: 1 },
|
|
86
|
-
//
|
|
92
|
+
// adjustedDtForHour: "2000-01-01T18:00:00.000+09:00"
|
|
87
93
|
// }
|
|
88
94
|
// }
|
|
89
95
|
```
|
|
@@ -126,7 +132,7 @@ import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
|
|
|
126
132
|
const adapter = await createDateFnsAdapter();
|
|
127
133
|
|
|
128
134
|
const dt = {
|
|
129
|
-
date: new Date(
|
|
135
|
+
date: new Date(1985, 4, 15, 14, 30), // Note: month is 0-indexed
|
|
130
136
|
timeZone: "Asia/Seoul",
|
|
131
137
|
};
|
|
132
138
|
|
|
@@ -228,11 +234,17 @@ function getFourPillars<T>(
|
|
|
228
234
|
month: string;
|
|
229
235
|
day: string;
|
|
230
236
|
hour: string;
|
|
237
|
+
lunar: {
|
|
238
|
+
lunarYear: number;
|
|
239
|
+
lunarMonth: number;
|
|
240
|
+
lunarDay: number;
|
|
241
|
+
isLeapMonth: boolean;
|
|
242
|
+
};
|
|
231
243
|
meta: {
|
|
232
|
-
|
|
244
|
+
solarYearUsed: number;
|
|
233
245
|
sunLonDeg: number;
|
|
234
246
|
effectiveDayDate: { year: number; month: number; day: number };
|
|
235
|
-
|
|
247
|
+
adjustedDtForHour: string;
|
|
236
248
|
};
|
|
237
249
|
}
|
|
238
250
|
```
|
|
@@ -245,7 +257,7 @@ function getFourPillars<T>(
|
|
|
245
257
|
- `preset`: Configuration preset (use `STANDARD_PRESET` or `TRADITIONAL_PRESET`)
|
|
246
258
|
- `tzOffsetHours`: Optional timezone offset in hours (default: 9 for KST)
|
|
247
259
|
|
|
248
|
-
**Returns:** Object with year, month, day, hour pillars and metadata
|
|
260
|
+
**Returns:** Object with year, month, day, hour pillars, lunar date, and metadata
|
|
249
261
|
|
|
250
262
|
#### `yearPillar(adapter, datetime)`
|
|
251
263
|
|
|
@@ -291,6 +303,58 @@ function dayPillarFromDate(date: {
|
|
|
291
303
|
}
|
|
292
304
|
```
|
|
293
305
|
|
|
306
|
+
### Lunar Conversion Functions
|
|
307
|
+
|
|
308
|
+
#### `getLunarDate(year, month, day)`
|
|
309
|
+
|
|
310
|
+
Convert a solar (Gregorian) date to a lunar date.
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
function getLunarDate(
|
|
314
|
+
year: number,
|
|
315
|
+
month: number,
|
|
316
|
+
day: number
|
|
317
|
+
): {
|
|
318
|
+
lunarYear: number;
|
|
319
|
+
lunarMonth: number;
|
|
320
|
+
lunarDay: number;
|
|
321
|
+
isLeapMonth: boolean;
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Example:**
|
|
326
|
+
```typescript
|
|
327
|
+
import { getLunarDate } from "@gracefullight/saju";
|
|
328
|
+
|
|
329
|
+
const lunar = getLunarDate(2000, 1, 1);
|
|
330
|
+
// { lunarYear: 1999, lunarMonth: 11, lunarDay: 25, isLeapMonth: false }
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### `getSolarDate(lunarYear, lunarMonth, lunarDay, isLeapMonth)`
|
|
334
|
+
|
|
335
|
+
Convert a lunar date to a solar (Gregorian) date.
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
function getSolarDate(
|
|
339
|
+
lunarYear: number,
|
|
340
|
+
lunarMonth: number,
|
|
341
|
+
lunarDay: number,
|
|
342
|
+
isLeapMonth?: boolean
|
|
343
|
+
): {
|
|
344
|
+
year: number;
|
|
345
|
+
month: number;
|
|
346
|
+
day: number;
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Example:**
|
|
351
|
+
```typescript
|
|
352
|
+
import { getSolarDate } from "@gracefullight/saju";
|
|
353
|
+
|
|
354
|
+
const solar = getSolarDate(1999, 11, 25, false);
|
|
355
|
+
// { year: 2000, month: 1, day: 1 }
|
|
356
|
+
```
|
|
357
|
+
|
|
294
358
|
#### `hourPillar(adapter, datetime, options)`
|
|
295
359
|
|
|
296
360
|
Calculate only the hour pillar with optional solar time correction.
|
|
@@ -445,7 +509,7 @@ const adapter = await createLuxonAdapter();
|
|
|
445
509
|
|
|
446
510
|
// New York birth time
|
|
447
511
|
const nyTime = DateTime.fromObject(
|
|
448
|
-
{ year:
|
|
512
|
+
{ year: 1985, month: 5, day: 15, hour: 6, minute: 30 },
|
|
449
513
|
{ zone: "America/New_York" }
|
|
450
514
|
);
|
|
451
515
|
|
|
@@ -470,7 +534,7 @@ const month = monthPillar(adapter, dt);
|
|
|
470
534
|
console.log(month.pillar, month.sunLonDeg);
|
|
471
535
|
|
|
472
536
|
// Day pillar (no adapter needed)
|
|
473
|
-
const day = dayPillarFromDate({ year:
|
|
537
|
+
const day = dayPillarFromDate({ year: 1985, month: 5, day: 15 });
|
|
474
538
|
console.log(day.pillar);
|
|
475
539
|
|
|
476
540
|
// Hour pillar with solar time
|
package/README.md
CHANGED
|
@@ -77,13 +77,19 @@ console.log(result);
|
|
|
77
77
|
// {
|
|
78
78
|
// year: "己卯", // 연주 (천간 + 지지)
|
|
79
79
|
// month: "丙子", // 월주
|
|
80
|
-
// day: "
|
|
81
|
-
// hour: "
|
|
80
|
+
// day: "辛巳", // 일주
|
|
81
|
+
// hour: "戊戌", // 시주
|
|
82
|
+
// lunar: {
|
|
83
|
+
// lunarYear: 1999,
|
|
84
|
+
// lunarMonth: 11,
|
|
85
|
+
// lunarDay: 25,
|
|
86
|
+
// isLeapMonth: false
|
|
87
|
+
// },
|
|
82
88
|
// meta: {
|
|
83
|
-
//
|
|
89
|
+
// solarYearUsed: 1999,
|
|
84
90
|
// sunLonDeg: 280.9,
|
|
85
91
|
// effectiveDayDate: { year: 2000, month: 1, day: 1 },
|
|
86
|
-
//
|
|
92
|
+
// adjustedDtForHour: "2000-01-01T18:00:00.000+09:00"
|
|
87
93
|
// }
|
|
88
94
|
// }
|
|
89
95
|
```
|
|
@@ -126,7 +132,7 @@ import { getFourPillars, STANDARD_PRESET } from "@gracefullight/saju";
|
|
|
126
132
|
const adapter = await createDateFnsAdapter();
|
|
127
133
|
|
|
128
134
|
const dt = {
|
|
129
|
-
date: new Date(
|
|
135
|
+
date: new Date(1985, 4, 15, 14, 30), // 주의: 월은 0부터 시작
|
|
130
136
|
timeZone: "Asia/Seoul",
|
|
131
137
|
};
|
|
132
138
|
|
|
@@ -228,11 +234,17 @@ function getFourPillars<T>(
|
|
|
228
234
|
month: string;
|
|
229
235
|
day: string;
|
|
230
236
|
hour: string;
|
|
237
|
+
lunar: {
|
|
238
|
+
lunarYear: number;
|
|
239
|
+
lunarMonth: number;
|
|
240
|
+
lunarDay: number;
|
|
241
|
+
isLeapMonth: boolean;
|
|
242
|
+
};
|
|
231
243
|
meta: {
|
|
232
|
-
|
|
244
|
+
solarYearUsed: number;
|
|
233
245
|
sunLonDeg: number;
|
|
234
246
|
effectiveDayDate: { year: number; month: number; day: number };
|
|
235
|
-
|
|
247
|
+
adjustedDtForHour: string;
|
|
236
248
|
};
|
|
237
249
|
}
|
|
238
250
|
```
|
|
@@ -245,7 +257,7 @@ function getFourPillars<T>(
|
|
|
245
257
|
- `preset`: 설정 프리셋 (`STANDARD_PRESET` 또는 `TRADITIONAL_PRESET` 사용)
|
|
246
258
|
- `tzOffsetHours`: 타임존 오프셋(시간 단위), 선택사항 (기본값: 9, KST)
|
|
247
259
|
|
|
248
|
-
**반환값:** 연월일시
|
|
260
|
+
**반환값:** 연월일시 기둥, 음력 날짜, 메타데이터를 포함한 객체
|
|
249
261
|
|
|
250
262
|
#### `yearPillar(adapter, datetime)`
|
|
251
263
|
|
|
@@ -291,6 +303,58 @@ function dayPillarFromDate(date: {
|
|
|
291
303
|
}
|
|
292
304
|
```
|
|
293
305
|
|
|
306
|
+
### 음력 변환 함수
|
|
307
|
+
|
|
308
|
+
#### `getLunarDate(year, month, day)`
|
|
309
|
+
|
|
310
|
+
양력(그레고리력) 날짜를 음력 날짜로 변환
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
function getLunarDate(
|
|
314
|
+
year: number,
|
|
315
|
+
month: number,
|
|
316
|
+
day: number
|
|
317
|
+
): {
|
|
318
|
+
lunarYear: number;
|
|
319
|
+
lunarMonth: number;
|
|
320
|
+
lunarDay: number;
|
|
321
|
+
isLeapMonth: boolean;
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**예시:**
|
|
326
|
+
```typescript
|
|
327
|
+
import { getLunarDate } from "@gracefullight/saju";
|
|
328
|
+
|
|
329
|
+
const lunar = getLunarDate(2000, 1, 1);
|
|
330
|
+
// { lunarYear: 1999, lunarMonth: 11, lunarDay: 25, isLeapMonth: false }
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### `getSolarDate(lunarYear, lunarMonth, lunarDay, isLeapMonth)`
|
|
334
|
+
|
|
335
|
+
음력 날짜를 양력(그레고리력) 날짜로 변환
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
function getSolarDate(
|
|
339
|
+
lunarYear: number,
|
|
340
|
+
lunarMonth: number,
|
|
341
|
+
lunarDay: number,
|
|
342
|
+
isLeapMonth?: boolean
|
|
343
|
+
): {
|
|
344
|
+
year: number;
|
|
345
|
+
month: number;
|
|
346
|
+
day: number;
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**예시:**
|
|
351
|
+
```typescript
|
|
352
|
+
import { getSolarDate } from "@gracefullight/saju";
|
|
353
|
+
|
|
354
|
+
const solar = getSolarDate(1999, 11, 25, false);
|
|
355
|
+
// { year: 2000, month: 1, day: 1 }
|
|
356
|
+
```
|
|
357
|
+
|
|
294
358
|
#### `hourPillar(adapter, datetime, options)`
|
|
295
359
|
|
|
296
360
|
태양시 보정 옵션과 함께 시주만 계산
|
|
@@ -445,7 +509,7 @@ const adapter = await createLuxonAdapter();
|
|
|
445
509
|
|
|
446
510
|
// 뉴욕 출생 시간
|
|
447
511
|
const nyTime = DateTime.fromObject(
|
|
448
|
-
{ year:
|
|
512
|
+
{ year: 1985, month: 5, day: 15, hour: 6, minute: 30 },
|
|
449
513
|
{ zone: "America/New_York" }
|
|
450
514
|
);
|
|
451
515
|
|
|
@@ -470,7 +534,7 @@ const month = monthPillar(adapter, dt);
|
|
|
470
534
|
console.log(month.pillar, month.sunLonDeg);
|
|
471
535
|
|
|
472
536
|
// 일주 (어댑터 불필요)
|
|
473
|
-
const day = dayPillarFromDate({ year:
|
|
537
|
+
const day = dayPillarFromDate({ year: 1985, month: 5, day: 15 });
|
|
474
538
|
console.log(day.pillar);
|
|
475
539
|
|
|
476
540
|
// 태양시를 사용한 시주
|
|
@@ -20,14 +20,14 @@ describe("Four Pillars Core", () => {
|
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
describe("dayPillarFromDate", () => {
|
|
23
|
-
it("should calculate day pillar for test case (
|
|
24
|
-
const result = dayPillarFromDate({ year:
|
|
25
|
-
expect(result.pillar).toBe("
|
|
26
|
-
expect(result.idx60).toBe(
|
|
23
|
+
it("should calculate day pillar for test case (1985-05-15 = 甲寅)", () => {
|
|
24
|
+
const result = dayPillarFromDate({ year: 1985, month: 5, day: 15 });
|
|
25
|
+
expect(result.pillar).toBe("甲寅");
|
|
26
|
+
expect(result.idx60).toBe(50);
|
|
27
27
|
});
|
|
28
28
|
it("should handle 60-day cycle correctly", () => {
|
|
29
|
-
const start = dayPillarFromDate({ year:
|
|
30
|
-
const after60 = dayPillarFromDate({ year:
|
|
29
|
+
const start = dayPillarFromDate({ year: 1985, month: 5, day: 15 });
|
|
30
|
+
const after60 = dayPillarFromDate({ year: 1985, month: 7, day: 14 });
|
|
31
31
|
expect(start.idx60).toBe(after60.idx60);
|
|
32
32
|
});
|
|
33
33
|
it("should calculate day pillar for leap year date", () => {
|
|
@@ -47,21 +47,21 @@ describe("Four Pillars Core", () => {
|
|
|
47
47
|
expect(result.pillar).toBe("甲子");
|
|
48
48
|
expect(result.solarYear).toBe(1984);
|
|
49
49
|
});
|
|
50
|
-
it("should calculate year pillar for
|
|
51
|
-
const dt = DateTime.fromObject({ year:
|
|
50
|
+
it("should calculate year pillar for 1985 (乙丑)", () => {
|
|
51
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
52
52
|
const result = yearPillar(adapter, dt);
|
|
53
|
-
expect(result.pillar).toBe("
|
|
54
|
-
expect(result.solarYear).toBe(
|
|
53
|
+
expect(result.pillar).toBe("乙丑");
|
|
54
|
+
expect(result.solarYear).toBe(1985);
|
|
55
55
|
});
|
|
56
56
|
it("should handle date before Lichun (立春)", () => {
|
|
57
|
-
const dt = DateTime.fromObject({ year:
|
|
57
|
+
const dt = DateTime.fromObject({ year: 1985, month: 1, day: 15 }, { zone: "Asia/Seoul" });
|
|
58
58
|
const result = yearPillar(adapter, dt);
|
|
59
|
-
expect(result.solarYear).toBe(
|
|
59
|
+
expect(result.solarYear).toBe(1984);
|
|
60
60
|
});
|
|
61
61
|
it("should handle date after Lichun", () => {
|
|
62
|
-
const dt = DateTime.fromObject({ year:
|
|
62
|
+
const dt = DateTime.fromObject({ year: 1985, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
63
63
|
const result = yearPillar(adapter, dt);
|
|
64
|
-
expect(result.solarYear).toBe(
|
|
64
|
+
expect(result.solarYear).toBe(1985);
|
|
65
65
|
});
|
|
66
66
|
it("should follow 60-year cycle", () => {
|
|
67
67
|
const dt1 = DateTime.fromObject({ year: 1984, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
@@ -72,25 +72,25 @@ describe("Four Pillars Core", () => {
|
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
74
|
describe("monthPillar", () => {
|
|
75
|
-
it("should calculate month pillar for test case (
|
|
76
|
-
const dt = DateTime.fromObject({ year:
|
|
75
|
+
it("should calculate month pillar for test case (1985-05-15)", () => {
|
|
76
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
77
77
|
const result = monthPillar(adapter, dt);
|
|
78
|
-
expect(result.pillar).toBe("
|
|
78
|
+
expect(result.pillar).toBe("辛巳");
|
|
79
79
|
});
|
|
80
80
|
it("should return valid stem-branch combination", () => {
|
|
81
|
-
const dt = DateTime.fromObject({ year:
|
|
81
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
82
82
|
const result = monthPillar(adapter, dt);
|
|
83
83
|
expect(result.pillar).toMatch(/^[甲乙丙丁戊己庚辛壬癸][子丑寅卯辰巳午未申酉戌亥]$/);
|
|
84
84
|
});
|
|
85
85
|
it("should include sun longitude in result", () => {
|
|
86
|
-
const dt = DateTime.fromObject({ year:
|
|
86
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
87
87
|
const result = monthPillar(adapter, dt);
|
|
88
88
|
expect(result.sunLonDeg).toBeGreaterThanOrEqual(0);
|
|
89
89
|
expect(result.sunLonDeg).toBeLessThan(360);
|
|
90
90
|
});
|
|
91
91
|
it("should calculate different months correctly", () => {
|
|
92
|
-
const jan = DateTime.fromObject({ year:
|
|
93
|
-
const jul = DateTime.fromObject({ year:
|
|
92
|
+
const jan = DateTime.fromObject({ year: 1985, month: 1, day: 15 }, { zone: "Asia/Seoul" });
|
|
93
|
+
const jul = DateTime.fromObject({ year: 1985, month: 7, day: 15 }, { zone: "Asia/Seoul" });
|
|
94
94
|
const result1 = monthPillar(adapter, jan);
|
|
95
95
|
const result2 = monthPillar(adapter, jul);
|
|
96
96
|
expect(result1.pillar).not.toBe(result2.pillar);
|
|
@@ -98,41 +98,41 @@ describe("Four Pillars Core", () => {
|
|
|
98
98
|
});
|
|
99
99
|
describe("effectiveDayDate", () => {
|
|
100
100
|
it("should return same date for midnight boundary before 23:00", () => {
|
|
101
|
-
const dt = DateTime.fromObject({ year:
|
|
101
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 22, minute: 30 }, { zone: "Asia/Seoul" });
|
|
102
102
|
const result = effectiveDayDate(adapter, dt, { dayBoundary: "midnight" });
|
|
103
|
-
expect(result.year).toBe(
|
|
104
|
-
expect(result.month).toBe(
|
|
105
|
-
expect(result.day).toBe(
|
|
103
|
+
expect(result.year).toBe(1985);
|
|
104
|
+
expect(result.month).toBe(5);
|
|
105
|
+
expect(result.day).toBe(15);
|
|
106
106
|
});
|
|
107
107
|
it("should advance date for zi23 boundary after 23:00", () => {
|
|
108
|
-
const dt = DateTime.fromObject({ year:
|
|
108
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 23, minute: 30 }, { zone: "Asia/Seoul" });
|
|
109
109
|
const result = effectiveDayDate(adapter, dt, { dayBoundary: "zi23" });
|
|
110
|
-
expect(result.year).toBe(
|
|
111
|
-
expect(result.month).toBe(
|
|
112
|
-
expect(result.day).toBe(
|
|
110
|
+
expect(result.year).toBe(1985);
|
|
111
|
+
expect(result.month).toBe(5);
|
|
112
|
+
expect(result.day).toBe(16);
|
|
113
113
|
});
|
|
114
114
|
it("should not advance date for zi23 boundary before 23:00", () => {
|
|
115
|
-
const dt = DateTime.fromObject({ year:
|
|
115
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 22, minute: 59 }, { zone: "Asia/Seoul" });
|
|
116
116
|
const result = effectiveDayDate(adapter, dt, { dayBoundary: "zi23" });
|
|
117
|
-
expect(result.year).toBe(
|
|
118
|
-
expect(result.month).toBe(
|
|
119
|
-
expect(result.day).toBe(
|
|
117
|
+
expect(result.year).toBe(1985);
|
|
118
|
+
expect(result.month).toBe(5);
|
|
119
|
+
expect(result.day).toBe(15);
|
|
120
120
|
});
|
|
121
121
|
it("should handle month boundary with zi23", () => {
|
|
122
|
-
const dt = DateTime.fromObject({ year:
|
|
122
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 31, hour: 23, minute: 30 }, { zone: "Asia/Seoul" });
|
|
123
123
|
const result = effectiveDayDate(adapter, dt, { dayBoundary: "zi23" });
|
|
124
|
-
expect(result.year).toBe(
|
|
125
|
-
expect(result.month).toBe(
|
|
124
|
+
expect(result.year).toBe(1985);
|
|
125
|
+
expect(result.month).toBe(6);
|
|
126
126
|
expect(result.day).toBe(1);
|
|
127
127
|
});
|
|
128
128
|
it("should apply mean solar time correction when enabled", () => {
|
|
129
|
-
const dt = DateTime.fromObject({ year:
|
|
129
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 23, minute: 50 }, { zone: "Asia/Seoul" });
|
|
130
130
|
const result = effectiveDayDate(adapter, dt, {
|
|
131
131
|
dayBoundary: "zi23",
|
|
132
132
|
longitudeDeg: 126.9,
|
|
133
133
|
useMeanSolarTimeForBoundary: true,
|
|
134
134
|
});
|
|
135
|
-
expect(result.day).toBe(
|
|
135
|
+
expect(result.day).toBe(16);
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
138
|
describe("hourPillar", () => {
|
|
@@ -175,7 +175,7 @@ describe("Four Pillars Core", () => {
|
|
|
175
175
|
});
|
|
176
176
|
expect(result.year).toBe("己卯");
|
|
177
177
|
expect(result.month).toBe("丙子");
|
|
178
|
-
expect(result.day).toBe("
|
|
178
|
+
expect(result.day).toBe("戊午");
|
|
179
179
|
expect(result.hour).toBe("辛酉");
|
|
180
180
|
});
|
|
181
181
|
it("should include metadata", () => {
|
|
@@ -189,6 +189,18 @@ describe("Four Pillars Core", () => {
|
|
|
189
189
|
expect(result.meta.effectiveDayDate).toEqual({ year: 2000, month: 1, day: 1 });
|
|
190
190
|
expect(result.meta.preset).toEqual(presetA);
|
|
191
191
|
});
|
|
192
|
+
it("should include lunar date information", () => {
|
|
193
|
+
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
194
|
+
const result = getFourPillars(adapter, dt, {
|
|
195
|
+
longitudeDeg: 126.9,
|
|
196
|
+
preset: presetA,
|
|
197
|
+
});
|
|
198
|
+
expect(result.lunar).toBeDefined();
|
|
199
|
+
expect(result.lunar.lunarYear).toBe(1999);
|
|
200
|
+
expect(result.lunar.lunarMonth).toBe(11);
|
|
201
|
+
expect(result.lunar.lunarDay).toBe(25);
|
|
202
|
+
expect(result.lunar.isLeapMonth).toBe(false);
|
|
203
|
+
});
|
|
192
204
|
});
|
|
193
205
|
describe("getFourPillars - Preset B", () => {
|
|
194
206
|
it("should calculate four pillars with preset B", () => {
|
|
@@ -274,7 +286,7 @@ describe("Four Pillars Core", () => {
|
|
|
274
286
|
expect(resultSeoul.day).toBe(resultTokyo.day);
|
|
275
287
|
});
|
|
276
288
|
it("should handle different longitudes affecting hour pillar", () => {
|
|
277
|
-
const dt = DateTime.fromObject({ year:
|
|
289
|
+
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 0, minute: 30 }, { zone: "UTC" });
|
|
278
290
|
const westLong = getFourPillars(adapter, dt, {
|
|
279
291
|
longitudeDeg: -120,
|
|
280
292
|
preset: presetB,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lunar.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/lunar.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { getLunarDate, getSolarDate } from "@/core/lunar";
|
|
3
|
+
describe("Lunar Calendar", () => {
|
|
4
|
+
describe("getLunarDate", () => {
|
|
5
|
+
it("should convert solar date to lunar date (2000-01-01)", () => {
|
|
6
|
+
const result = getLunarDate(2000, 1, 1);
|
|
7
|
+
expect(result.lunarYear).toBe(1999);
|
|
8
|
+
expect(result.lunarMonth).toBe(11);
|
|
9
|
+
expect(result.lunarDay).toBe(25);
|
|
10
|
+
expect(result.isLeapMonth).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
it("should convert solar date to lunar date (1985-05-15)", () => {
|
|
13
|
+
const result = getLunarDate(1985, 5, 15);
|
|
14
|
+
expect(result.lunarYear).toBe(1985);
|
|
15
|
+
expect(result.lunarMonth).toBe(3);
|
|
16
|
+
expect(result.lunarDay).toBe(26);
|
|
17
|
+
expect(result.isLeapMonth).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
it("should handle leap month correctly (2023-03-22 is in leap 2nd month)", () => {
|
|
20
|
+
const result = getLunarDate(2023, 3, 22);
|
|
21
|
+
expect(result.lunarYear).toBe(2023);
|
|
22
|
+
expect(result.lunarMonth).toBe(2);
|
|
23
|
+
expect(result.isLeapMonth).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
it("should convert first day of lunar year", () => {
|
|
26
|
+
const result = getLunarDate(2024, 2, 10);
|
|
27
|
+
expect(result.lunarYear).toBe(2024);
|
|
28
|
+
expect(result.lunarMonth).toBe(1);
|
|
29
|
+
expect(result.lunarDay).toBe(1);
|
|
30
|
+
expect(result.isLeapMonth).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("getSolarDate", () => {
|
|
34
|
+
it("should convert lunar date to solar date", () => {
|
|
35
|
+
const result = getSolarDate(1999, 11, 25, false);
|
|
36
|
+
expect(result.year).toBe(2000);
|
|
37
|
+
expect(result.month).toBe(1);
|
|
38
|
+
expect(result.day).toBe(1);
|
|
39
|
+
});
|
|
40
|
+
it("should convert lunar date (1985-03-26) to solar date", () => {
|
|
41
|
+
const result = getSolarDate(1985, 3, 26, false);
|
|
42
|
+
expect(result.year).toBe(1985);
|
|
43
|
+
expect(result.month).toBe(5);
|
|
44
|
+
expect(result.day).toBe(15);
|
|
45
|
+
});
|
|
46
|
+
it("should handle leap month in reverse conversion", () => {
|
|
47
|
+
const result = getSolarDate(2023, 2, 1, true);
|
|
48
|
+
expect(result.year).toBe(2023);
|
|
49
|
+
expect(result.month).toBe(3);
|
|
50
|
+
expect(result.day).toBe(22);
|
|
51
|
+
});
|
|
52
|
+
it("should convert first day of lunar year 2024", () => {
|
|
53
|
+
const result = getSolarDate(2024, 1, 1, false);
|
|
54
|
+
expect(result.year).toBe(2024);
|
|
55
|
+
expect(result.month).toBe(2);
|
|
56
|
+
expect(result.day).toBe(10);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("round-trip conversion", () => {
|
|
60
|
+
it("should convert solar -> lunar -> solar correctly", () => {
|
|
61
|
+
const original = { year: 2000, month: 6, day: 15 };
|
|
62
|
+
const lunar = getLunarDate(original.year, original.month, original.day);
|
|
63
|
+
const backToSolar = getSolarDate(lunar.lunarYear, lunar.lunarMonth, lunar.lunarDay, lunar.isLeapMonth);
|
|
64
|
+
expect(backToSolar.year).toBe(original.year);
|
|
65
|
+
expect(backToSolar.month).toBe(original.month);
|
|
66
|
+
expect(backToSolar.day).toBe(original.day);
|
|
67
|
+
});
|
|
68
|
+
it("should handle various dates in round-trip", () => {
|
|
69
|
+
const testDates = [
|
|
70
|
+
{ year: 1990, month: 3, day: 20 },
|
|
71
|
+
{ year: 2010, month: 8, day: 1 },
|
|
72
|
+
{ year: 2020, month: 12, day: 31 },
|
|
73
|
+
];
|
|
74
|
+
for (const date of testDates) {
|
|
75
|
+
const lunar = getLunarDate(date.year, date.month, date.day);
|
|
76
|
+
const backToSolar = getSolarDate(lunar.lunarYear, lunar.lunarMonth, lunar.lunarDay, lunar.isLeapMonth);
|
|
77
|
+
expect(backToSolar.year).toBe(date.year);
|
|
78
|
+
expect(backToSolar.month).toBe(date.month);
|
|
79
|
+
expect(backToSolar.day).toBe(date.day);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DateAdapter } from "@/adapters/date-adapter";
|
|
2
|
+
import { type LunarDate } from "@/core/lunar";
|
|
2
3
|
export declare const STEMS: string[];
|
|
3
4
|
export declare const BRANCHES: string[];
|
|
4
5
|
export declare const STANDARD_PRESET: {
|
|
@@ -73,6 +74,7 @@ export declare function getFourPillars<T>(adapter: DateAdapter<T>, dtLocal: T, {
|
|
|
73
74
|
month: string;
|
|
74
75
|
day: string;
|
|
75
76
|
hour: string;
|
|
77
|
+
lunar: LunarDate;
|
|
76
78
|
meta: {
|
|
77
79
|
solarYearUsed: number;
|
|
78
80
|
sunLonDeg: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getLunarDate } from "@/core/lunar";
|
|
1
2
|
export const STEMS = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
|
|
2
3
|
export const BRANCHES = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
|
|
3
4
|
export const STANDARD_PRESET = {
|
|
@@ -33,7 +34,7 @@ function jdnFromDate(y, m, d) {
|
|
|
33
34
|
}
|
|
34
35
|
export function dayPillarFromDate({ year, month, day, }) {
|
|
35
36
|
const jdn = jdnFromDate(year, month, day);
|
|
36
|
-
const idx60 = (jdn +
|
|
37
|
+
const idx60 = (((jdn - 11) % 60) + 60) % 60;
|
|
37
38
|
return { idx60, pillar: pillarFrom60(idx60) };
|
|
38
39
|
}
|
|
39
40
|
export function applyMeanSolarTime(adapter, dtLocal, longitudeDeg, tzOffsetHours = 9) {
|
|
@@ -160,9 +161,9 @@ function hourBranchIndexFromHour(h) {
|
|
|
160
161
|
// Traditional Chinese hours (時辰) mapping:
|
|
161
162
|
// Each branch represents a 2-hour period, starting from 子時 at 23:00
|
|
162
163
|
// 子時 (0): 23:00-01:00, 丑時 (1): 01:00-03:00, ..., 亥時 (11): 21:00-23:00
|
|
163
|
-
// Formula: (hour + 1) / 2
|
|
164
|
-
//
|
|
165
|
-
return Math.floor((h + 1) / 2
|
|
164
|
+
// Formula: floor((hour + 1) / 2) % 12
|
|
165
|
+
// Examples: 0->0(子), 1->1(丑), 3->2(寅), 23->0(子)
|
|
166
|
+
return Math.floor((h + 1) / 2) % 12;
|
|
166
167
|
}
|
|
167
168
|
export function hourPillar(adapter, dtLocal, { longitudeDeg, tzOffsetHours = 9, useMeanSolarTimeForHour = false, dayBoundary = "midnight", useMeanSolarTimeForBoundary = false, } = {}) {
|
|
168
169
|
let dtUsed = dtLocal;
|
|
@@ -205,11 +206,13 @@ export function getFourPillars(adapter, dtLocal, { longitudeDeg, tzOffsetHours =
|
|
|
205
206
|
dayBoundary,
|
|
206
207
|
useMeanSolarTimeForBoundary,
|
|
207
208
|
});
|
|
209
|
+
const lunar = getLunarDate(effDate.year, effDate.month, effDate.day);
|
|
208
210
|
return {
|
|
209
211
|
year: y.pillar,
|
|
210
212
|
month: m.pillar,
|
|
211
213
|
day: d.pillar,
|
|
212
214
|
hour: h.pillar,
|
|
215
|
+
lunar,
|
|
213
216
|
meta: {
|
|
214
217
|
solarYearUsed: y.solarYear,
|
|
215
218
|
sunLonDeg: m.sunLonDeg,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface LunarDate {
|
|
2
|
+
lunarYear: number;
|
|
3
|
+
lunarMonth: number;
|
|
4
|
+
lunarDay: number;
|
|
5
|
+
isLeapMonth: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function getLunarDate(year: number, month: number, day: number): LunarDate;
|
|
8
|
+
export declare function getSolarDate(lunarYear: number, lunarMonth: number, lunarDay: number, isLeapMonth?: boolean): {
|
|
9
|
+
year: number;
|
|
10
|
+
month: number;
|
|
11
|
+
day: number;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=lunar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lunar.d.ts","sourceRoot":"","sources":["../../src/core/lunar.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAYhF;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,UAAQ,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAW9C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Lunar, Solar } from "lunar-javascript";
|
|
2
|
+
export function getLunarDate(year, month, day) {
|
|
3
|
+
const solar = Solar.fromYmd(year, month, day);
|
|
4
|
+
const lunar = solar.getLunar();
|
|
5
|
+
const rawMonth = lunar.getMonth();
|
|
6
|
+
const isLeapMonth = rawMonth < 0;
|
|
7
|
+
return {
|
|
8
|
+
lunarYear: lunar.getYear(),
|
|
9
|
+
lunarMonth: isLeapMonth ? Math.abs(rawMonth) : rawMonth,
|
|
10
|
+
lunarDay: lunar.getDay(),
|
|
11
|
+
isLeapMonth,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function getSolarDate(lunarYear, lunarMonth, lunarDay, isLeapMonth = false) {
|
|
15
|
+
// lunar-javascript uses negative month for leap months
|
|
16
|
+
const month = isLeapMonth ? -lunarMonth : lunarMonth;
|
|
17
|
+
const lunar = Lunar.fromYmd(lunarYear, month, lunarDay);
|
|
18
|
+
const solar = lunar.getSolar();
|
|
19
|
+
return {
|
|
20
|
+
year: solar.getYear(),
|
|
21
|
+
month: solar.getMonth(),
|
|
22
|
+
day: solar.getDay(),
|
|
23
|
+
};
|
|
24
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type { DateAdapter } from "@/adapters/date-adapter";
|
|
2
|
+
export { getLunarDate, getSolarDate, type LunarDate } from "@/core/lunar";
|
|
2
3
|
export { applyMeanSolarTime, BRANCHES, dayPillarFromDate, effectiveDayDate, getFourPillars, hourPillar, monthPillar, presetA, presetB, STANDARD_PRESET, STEMS, TRADITIONAL_PRESET, yearPillar, } from "@/core/four-pillars";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,WAAW,EACX,OAAO,EACP,OAAO,EACP,eAAe,EACf,KAAK,EACL,kBAAkB,EAClB,UAAU,GACX,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,WAAW,EACX,OAAO,EACP,OAAO,EACP,eAAe,EACf,KAAK,EACL,kBAAkB,EAClB,UAAU,GACX,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
+
export { getLunarDate, getSolarDate } from "@/core/lunar";
|
|
1
2
|
export { applyMeanSolarTime, BRANCHES, dayPillarFromDate, effectiveDayDate, getFourPillars, hourPillar, monthPillar, presetA, presetB, STANDARD_PRESET, STEMS, TRADITIONAL_PRESET, yearPillar, } from "@/core/four-pillars";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gracefullight/saju",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Four Pillars (四柱) calculator with flexible date adapter support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,5 +66,8 @@
|
|
|
66
66
|
"date-fns-tz": "^3.2.0",
|
|
67
67
|
"luxon": "^3.5.0",
|
|
68
68
|
"vitest": "^2.1.8"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"lunar-javascript": "^1.7.7"
|
|
69
72
|
}
|
|
70
73
|
}
|