kor-lunar 1.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 카유 (kahyou22)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # kor-lunar
2
+
3
+ 한국천문연구원(KASI)에서 제공하는 음력/양력 데이터를 기반으로 오프라인 환경에서도 사용 할 수 있도록 구현된 라이브러리입니다.
4
+
5
+ 이 라이브러리는 학습용으로 제작되었으며, 2016년 이후로 데이터를 갱신하지 않아 최신 변경 사항이 반영되지 않았을 수 있습니다.
6
+
7
+ 정확한 정보가 필요한 중요한 작업에는 아래 출처의 공식 API를 통해 데이터를 직접 조회하시기 바랍니다.
8
+
9
+ ## 출처 및 참고 자료
10
+
11
+ - 한국천문연구원: https://www.kasi.re.kr
12
+ - 공공데이터포털: https://www.data.go.kr/data/15012679/openapi.do
@@ -0,0 +1,7 @@
1
+ import { toLunar, toSolar } from "./kor-lunar";
2
+ declare const korLunar: {
3
+ toLunar: (solYear: number, solMonth: number, solDay: number) => import("./kor-lunar").LunarDate;
4
+ toSolar: (lunYear: number, lunMonth: number, lunDay: number, isLeapMonth: boolean) => import("./kor-lunar").SolarDate;
5
+ };
6
+ export default korLunar;
7
+ export { toLunar, toSolar };
@@ -0,0 +1,15 @@
1
+ interface LunarDate {
2
+ year: number;
3
+ month: number;
4
+ day: number;
5
+ isLeapMonth: boolean;
6
+ }
7
+ interface SolarDate {
8
+ year: number;
9
+ month: number;
10
+ day: number;
11
+ }
12
+ declare const toLunar: (solYear: number, solMonth: number, solDay: number) => LunarDate;
13
+ declare const toSolar: (lunYear: number, lunMonth: number, lunDay: number, isLeapMonth: boolean) => SolarDate;
14
+ export type { LunarDate, SolarDate };
15
+ export { toLunar, toSolar };
@@ -0,0 +1,285 @@
1
+ /**
2
+ * 음력 테이블
3
+ *
4
+ * 9b (17-25): 해당 해의 총 음력 일 수 (예: 384)
5
+ *
6
+ * 1b ( 16): 윤달의 크기 (0: 29일, 1: 30일)
7
+ *
8
+ * 4b (12-15): 윤달 위치 (1-12, 윤달이 없으면 0)
9
+ *
10
+ * 12b ( 0-11): 각 월의 크기 (0: 29일, 1: 30일)
11
+ */
12
+ var LUN_TABLE = [
13
+ /* 0 1 2 3 4 5 6 7 8 9 */
14
+ /*1890*/ 0x3002ab6, 0x2c60daa, 0x3006ee4, 0x2c40ea4, 0x2c40d4a, 0x2fe5555, 0x2c60a97, 0x2c40556, 0x300355d, 0x2c60ad5,
15
+ /*1900*/ 0x3008bd2, 0x2c40752, 0x2c60ea5, 0x2fe5b2a, 0x2c4064b, 0x2c60a9b, 0x3014aa6, 0x2c4056a, 0x2c60b59, 0x3002baa,
16
+ /*1910*/ 0x2c40752, 0x3006da5, 0x2c40b25, 0x2c40a4b, 0x300595b, 0x2c60aad, 0x2c4056a, 0x30025b5, 0x2c60ba9, 0x3007dd2,
17
+ /*1920*/ 0x2c40d92, 0x2c40d25, 0x3005d2d, 0x2c40956, 0x2c402b5, 0x3024add, 0x2c406d4, 0x2c60da9, 0x3002eca, 0x2c40e92,
18
+ /*1930*/ 0x2fe66a6, 0x2c40527, 0x2c60a57, 0x3015956, 0x2c60ada, 0x2c406d4, 0x3013751, 0x2c40749, 0x3017b13, 0x2c40a93,
19
+ /*1940*/ 0x2c4052b, 0x301651b, 0x2c6096d, 0x2c60b6a, 0x3014da4, 0x2c40ba4, 0x2c40b49, 0x3002d4b, 0x2c40a95, 0x3007aab,
20
+ /*1950*/ 0x2c4052d, 0x2c60aad, 0x3015aaa, 0x2c60db2, 0x2c40da4, 0x3013ea1, 0x2c40d4a, 0x3008d95, 0x2c40a96, 0x2c40556,
21
+ /*1960*/ 0x3006575, 0x2c60ad5, 0x2c406d2, 0x3004755, 0x2c60ea5, 0x2c40e4a, 0x2fe364e, 0x2c60a9b, 0x3007ad6, 0x2c4056a,
22
+ /*1970*/ 0x2c60b59, 0x3005bb2, 0x2c40752, 0x2c40725, 0x3004b2b, 0x2c40a4b, 0x30089ab, 0x2c402ad, 0x2c6056b, 0x30165a9,
23
+ /*1980*/ 0x2c60da9, 0x2c40d92, 0x3004d95, 0x2c40d25, 0x300ae4d, 0x2c40a56, 0x2c402b6, 0x3026aed, 0x2c406d4, 0x2c60da9,
24
+ /*1990*/ 0x3005ed2, 0x2c40e92, 0x2c40d26, 0x2fe352e, 0x2c60a57, 0x30089b6, 0x2c60b5a, 0x2c406d4, 0x3005769, 0x2c40749,
25
+ /*2000*/ 0x2c40693, 0x3004a97, 0x2c4052b, 0x2c60a5b, 0x3002aae, 0x2c4036a, 0x3027dd5, 0x2c40ba4, 0x2c40b49, 0x3005d53,
26
+ /*2010*/ 0x2c40a95, 0x2c4052d, 0x301352d, 0x2c60aad, 0x3009baa, 0x2c405d2, 0x2c60da5, 0x3005eaa, 0x2c40d4a, 0x2c40a95,
27
+ /*2020*/ 0x3004a9d, 0x2c40556, 0x2c60ab5, 0x3002ad6, 0x2c406d2, 0x3006765, 0x2c60ea5, 0x2c40e4a, 0x2fe5656, 0x2c60c9b,
28
+ /*2030*/ 0x2c4055a, 0x300356d, 0x2c60b69, 0x300bf52, 0x2c40752, 0x2c40b25, 0x3016b0b, 0x2c40a4b, 0x2c404ab, 0x30052bb,
29
+ /*2040*/ 0x2c6056d, 0x2c60b69, 0x3002daa, 0x2c40d92, 0x3007ea5, 0x2c40d25, 0x2c40a4d, 0x3015a4d, 0x2c402b6, 0x2c605b5,
30
+ ];
31
+ var BASE_YEAR$1 = 1890;
32
+ var BASE_MONTH$1 = 1;
33
+ var BASE_DAY$1 = 1;
34
+ var MAX_YEAR$1 = 2049;
35
+ var MAX_MONTH$1 = 12;
36
+ var MAX_DAY$1 = 29;
37
+ var SMALL_MONTH_DAY = 29;
38
+ var BIG_MONTH_DAY = 30;
39
+ var totalDaysBeforeYear$1 = {};
40
+ var getYearData = function (year) {
41
+ return LUN_TABLE[year - BASE_YEAR$1];
42
+ };
43
+ /**
44
+ * 해당 월 (평달)의 일 수를 반환합니다.
45
+ * @param year 1890년 ~ 2049년
46
+ * @param month 1월 ~ 12월
47
+ * @returns 월의 일 수 (29 또는 30)
48
+ */
49
+ var getMonthDays$1 = function (year, month) {
50
+ var monthType = (getYearData(year) >> (month - 1)) & 0x1;
51
+ return monthType === 0 ? SMALL_MONTH_DAY : BIG_MONTH_DAY;
52
+ };
53
+ /**
54
+ * 해당 연도의 윤달을 반환합니다.
55
+ * @param year 1890년 ~ 2049년
56
+ * @returns 윤달 월 (1월 ~ 12월), 없으면 0
57
+ */
58
+ var getLeapMonth = function (year) {
59
+ return (getYearData(year) >> 12) & 0xf;
60
+ };
61
+ /**
62
+ * 해당 연도에 윤달이 있는지를 반환합니다.
63
+ * @param year 1890년 ~ 2049년
64
+ * @return 윤달이 있으면 true
65
+ */
66
+ var hasLeapMonth = function (year) {
67
+ return getLeapMonth(year) !== 0;
68
+ };
69
+ /**
70
+ * 해당 월이 윤달인지를 반환합니다.
71
+ * @param year 1890년 ~ 2049년
72
+ * @param month 1월 ~ 12월
73
+ * @returns 윤달이면 true
74
+ */
75
+ var isLeapMonth = function (year, month) {
76
+ return month === getLeapMonth(year);
77
+ };
78
+ /**
79
+ * 해당 월 (윤달)의 일 수를 반환합니다.
80
+ * @param year 1890년 ~ 2049년
81
+ * @param month 1월 ~ 12월
82
+ * @returns 윤달의 일 수 (29 또는 30), 윤달이 아니면 0
83
+ */
84
+ var getLeapMonthDays = function (year, month) {
85
+ if (!isLeapMonth(year, month))
86
+ return 0;
87
+ var monthType = (getYearData(year) >> 16) & 0x1;
88
+ return monthType === 0 ? SMALL_MONTH_DAY : BIG_MONTH_DAY;
89
+ };
90
+ /**
91
+ * 해당 연도의 총 일 수를 반환합니다.
92
+ * @param year 1890년 ~ 2049년
93
+ * @return 해당 연도의 총 일 수
94
+ */
95
+ var getYearDays$1 = function (year) {
96
+ return (getYearData(year) >> 17) & 0x1ff;
97
+ };
98
+ /**
99
+ * 연도별 누적 일 수를 초기에 룩업 테이블로 생성하여
100
+ * O(1)으로 누적 일 수를 가져오게 변환함
101
+ */
102
+ totalDaysBeforeYear$1[BASE_YEAR$1] = 0;
103
+ for (var y$1 = BASE_YEAR$1 + 1; y$1 < MAX_YEAR$1; y$1++) {
104
+ totalDaysBeforeYear$1[y$1] = totalDaysBeforeYear$1[y$1 - 1] + getYearDays$1(y$1 - 1);
105
+ }
106
+ /**
107
+ * 1890년부터 해당 연도 전까지의 누적 일 수를 반환합니다.
108
+ * @param year 1890년 ~ 2049년
109
+ * @return 해당 연도 전까지의 누적 일 수
110
+ */
111
+ var getTotalDaysBeforeYear$1 = function (year) {
112
+ var days = totalDaysBeforeYear$1[year];
113
+ return days;
114
+ };
115
+ /**
116
+ * 해당 연도 내에서 해당 월 (및 윤달 포함) 전까지의 누적 일 수를 반환합니다.
117
+ * @param year 1890년 ~ 2049년
118
+ * @param month 1월 ~ 12월
119
+ * @param isLeapMonth 대상이 윤달이면 true
120
+ * @returns 해당 연도 내, 해당 월 전까지의 누적 일 수
121
+ */
122
+ var getTotalDaysBeforeMonth$1 = function (year, month, isLeapMonth) {
123
+ var days = 0;
124
+ // 해당 월 전까지 윤달을 포함하여 누적
125
+ for (var m = 1; m < month; m++) {
126
+ days += getMonthDays$1(year, m);
127
+ if (m === getLeapMonth(year)) {
128
+ days += getLeapMonthDays(year, m);
129
+ }
130
+ }
131
+ // 대상이 윤달이면, 앞에 있는 평달을 누적
132
+ var leapMonth = getLeapMonth(year);
133
+ if (isLeapMonth && leapMonth === month) {
134
+ days += getMonthDays$1(year, month);
135
+ }
136
+ return days;
137
+ };
138
+ /**
139
+ * 1890년부터 해당 연도, 월, 일 (및 윤달 포함) 까지의 누적 일 수를 반환합니다.
140
+ * @param year 1890년 ~ 2049년
141
+ * @param month 1월 ~ 12월
142
+ * @param day 일자
143
+ * @param isLeapMonth 대상이 윤달이면 true
144
+ * @returns 총 누적 일 수
145
+ */
146
+ var getTotalDays$1 = function (year, month, day, isLeapMonth) {
147
+ var days = getTotalDaysBeforeYear$1(year) + getTotalDaysBeforeMonth$1(year, month, isLeapMonth) + day;
148
+ return days;
149
+ };
150
+ var LunarData = {
151
+ BASE_YEAR: BASE_YEAR$1,
152
+ BASE_MONTH: BASE_MONTH$1,
153
+ BASE_DAY: BASE_DAY$1,
154
+ MAX_YEAR: MAX_YEAR$1,
155
+ MAX_MONTH: MAX_MONTH$1,
156
+ MAX_DAY: MAX_DAY$1,
157
+ getMonthDays: getMonthDays$1,
158
+ getLeapMonth: getLeapMonth,
159
+ hasLeapMonth: hasLeapMonth,
160
+ isLeapMonth: isLeapMonth,
161
+ getLeapMonthDays: getLeapMonthDays,
162
+ getYearDays: getYearDays$1,
163
+ getTotalDaysBeforeYear: getTotalDaysBeforeYear$1,
164
+ getTotalDaysBeforeMonth: getTotalDaysBeforeMonth$1,
165
+ getTotalDays: getTotalDays$1,
166
+ };
167
+
168
+ var MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
169
+ var LEAP_FEBRUARY_DAY = 29;
170
+ var YEAR_DAY = 365;
171
+ var LEAP_YEAR_DAY = 366;
172
+ var BASE_YEAR = 1890;
173
+ var BASE_MONTH = 1;
174
+ var BASE_DAY = 21;
175
+ var MAX_YEAR = 2050;
176
+ var MAX_MONTH = 1;
177
+ var MAX_DAY = 22;
178
+ var totalDaysBeforeYear = {};
179
+ var isLeapYear = function (year) {
180
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
181
+ };
182
+ var getMonthDays = function (year, month) {
183
+ var day = month == 2 && isLeapYear(year) ? LEAP_FEBRUARY_DAY : MONTH_DAYS[month - 1];
184
+ return day;
185
+ };
186
+ var getYearDays = function (year) {
187
+ var day = isLeapYear(year) ? LEAP_YEAR_DAY : YEAR_DAY;
188
+ return day;
189
+ };
190
+ /**
191
+ * 연도별 누적 일 수를 초기에 룩업 테이블로 생성하여
192
+ * O(1)으로 누적 일 수를 가져오게 변환함
193
+ */
194
+ totalDaysBeforeYear[BASE_YEAR] = 0;
195
+ for (var y = BASE_YEAR + 1; y < MAX_YEAR; y++) {
196
+ totalDaysBeforeYear[y] = totalDaysBeforeYear[y - 1] + getYearDays(y - 1);
197
+ }
198
+ var getTotalDaysBeforeYear = function (year) {
199
+ var day = totalDaysBeforeYear[year];
200
+ return day;
201
+ };
202
+ var getTotalDaysBeforeMonth = function (year, month) {
203
+ var day = 0;
204
+ for (var m = 1; m < month; m++) {
205
+ day += getMonthDays(year, m);
206
+ }
207
+ return day;
208
+ };
209
+ var getTotalDays = function (year, month, day) {
210
+ var days = getTotalDaysBeforeYear(year) + getTotalDaysBeforeMonth(year, month) + day;
211
+ return days;
212
+ };
213
+ var SolarData = {
214
+ BASE_YEAR: BASE_YEAR,
215
+ BASE_MONTH: BASE_MONTH,
216
+ BASE_DAY: BASE_DAY,
217
+ MAX_YEAR: MAX_YEAR,
218
+ MAX_MONTH: MAX_MONTH,
219
+ MAX_DAY: MAX_DAY,
220
+ isLeapYear: isLeapYear,
221
+ getMonthDays: getMonthDays,
222
+ getYearDays: getYearDays,
223
+ getTotalDays: getTotalDays,
224
+ };
225
+
226
+ var SOLAR_LUNAR_DAY_DIFF = 20;
227
+ var toLunar = function (solYear, solMonth, solDay) {
228
+ var year = LunarData.BASE_YEAR;
229
+ var month = LunarData.BASE_MONTH;
230
+ var day = LunarData.BASE_DAY + SolarData.getTotalDays(solYear, solMonth, solDay) - SOLAR_LUNAR_DAY_DIFF - 1;
231
+ var yearDays = LunarData.getYearDays(year);
232
+ while (day > yearDays) {
233
+ year++;
234
+ day -= yearDays;
235
+ yearDays = LunarData.getYearDays(year);
236
+ }
237
+ var isLeapMonth = false;
238
+ var leapMonth = LunarData.getLeapMonth(year);
239
+ var monthDays = LunarData.getMonthDays(year, month);
240
+ while (day > monthDays) {
241
+ day -= monthDays;
242
+ isLeapMonth = false;
243
+ if (month === leapMonth) {
244
+ leapMonth = 0;
245
+ monthDays = LunarData.getLeapMonthDays(year, month);
246
+ isLeapMonth = true;
247
+ continue;
248
+ }
249
+ month++;
250
+ if (month > 12) {
251
+ month = 1;
252
+ year++;
253
+ leapMonth = LunarData.getLeapMonth(year);
254
+ }
255
+ monthDays = LunarData.getMonthDays(year, month);
256
+ }
257
+ return { year: year, month: month, day: day, isLeapMonth: isLeapMonth };
258
+ };
259
+ var toSolar = function (lunYear, lunMonth, lunDay, isLeapMonth) {
260
+ var year = SolarData.BASE_YEAR;
261
+ var month = SolarData.BASE_MONTH;
262
+ var day = SolarData.BASE_DAY + LunarData.getTotalDays(lunYear, lunMonth, lunDay, isLeapMonth) - 1;
263
+ var yearDays = SolarData.getYearDays(year);
264
+ while (day > yearDays) {
265
+ day -= yearDays;
266
+ year++;
267
+ yearDays = SolarData.getYearDays(year);
268
+ }
269
+ var monthDays = SolarData.getMonthDays(year, month);
270
+ while (day > monthDays) {
271
+ day -= monthDays;
272
+ month++;
273
+ if (month > 12) {
274
+ month = 1;
275
+ year++;
276
+ }
277
+ monthDays = SolarData.getMonthDays(year, month);
278
+ }
279
+ return { year: year, month: month, day: day };
280
+ };
281
+
282
+ var korLunar = { toLunar: toLunar, toSolar: toSolar };
283
+
284
+ export { korLunar as default, toLunar, toSolar };
285
+ //# sourceMappingURL=kor-lunar.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kor-lunar.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,291 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ /**
6
+ * 음력 테이블
7
+ *
8
+ * 9b (17-25): 해당 해의 총 음력 일 수 (예: 384)
9
+ *
10
+ * 1b ( 16): 윤달의 크기 (0: 29일, 1: 30일)
11
+ *
12
+ * 4b (12-15): 윤달 위치 (1-12, 윤달이 없으면 0)
13
+ *
14
+ * 12b ( 0-11): 각 월의 크기 (0: 29일, 1: 30일)
15
+ */
16
+ var LUN_TABLE = [
17
+ /* 0 1 2 3 4 5 6 7 8 9 */
18
+ /*1890*/ 0x3002ab6, 0x2c60daa, 0x3006ee4, 0x2c40ea4, 0x2c40d4a, 0x2fe5555, 0x2c60a97, 0x2c40556, 0x300355d, 0x2c60ad5,
19
+ /*1900*/ 0x3008bd2, 0x2c40752, 0x2c60ea5, 0x2fe5b2a, 0x2c4064b, 0x2c60a9b, 0x3014aa6, 0x2c4056a, 0x2c60b59, 0x3002baa,
20
+ /*1910*/ 0x2c40752, 0x3006da5, 0x2c40b25, 0x2c40a4b, 0x300595b, 0x2c60aad, 0x2c4056a, 0x30025b5, 0x2c60ba9, 0x3007dd2,
21
+ /*1920*/ 0x2c40d92, 0x2c40d25, 0x3005d2d, 0x2c40956, 0x2c402b5, 0x3024add, 0x2c406d4, 0x2c60da9, 0x3002eca, 0x2c40e92,
22
+ /*1930*/ 0x2fe66a6, 0x2c40527, 0x2c60a57, 0x3015956, 0x2c60ada, 0x2c406d4, 0x3013751, 0x2c40749, 0x3017b13, 0x2c40a93,
23
+ /*1940*/ 0x2c4052b, 0x301651b, 0x2c6096d, 0x2c60b6a, 0x3014da4, 0x2c40ba4, 0x2c40b49, 0x3002d4b, 0x2c40a95, 0x3007aab,
24
+ /*1950*/ 0x2c4052d, 0x2c60aad, 0x3015aaa, 0x2c60db2, 0x2c40da4, 0x3013ea1, 0x2c40d4a, 0x3008d95, 0x2c40a96, 0x2c40556,
25
+ /*1960*/ 0x3006575, 0x2c60ad5, 0x2c406d2, 0x3004755, 0x2c60ea5, 0x2c40e4a, 0x2fe364e, 0x2c60a9b, 0x3007ad6, 0x2c4056a,
26
+ /*1970*/ 0x2c60b59, 0x3005bb2, 0x2c40752, 0x2c40725, 0x3004b2b, 0x2c40a4b, 0x30089ab, 0x2c402ad, 0x2c6056b, 0x30165a9,
27
+ /*1980*/ 0x2c60da9, 0x2c40d92, 0x3004d95, 0x2c40d25, 0x300ae4d, 0x2c40a56, 0x2c402b6, 0x3026aed, 0x2c406d4, 0x2c60da9,
28
+ /*1990*/ 0x3005ed2, 0x2c40e92, 0x2c40d26, 0x2fe352e, 0x2c60a57, 0x30089b6, 0x2c60b5a, 0x2c406d4, 0x3005769, 0x2c40749,
29
+ /*2000*/ 0x2c40693, 0x3004a97, 0x2c4052b, 0x2c60a5b, 0x3002aae, 0x2c4036a, 0x3027dd5, 0x2c40ba4, 0x2c40b49, 0x3005d53,
30
+ /*2010*/ 0x2c40a95, 0x2c4052d, 0x301352d, 0x2c60aad, 0x3009baa, 0x2c405d2, 0x2c60da5, 0x3005eaa, 0x2c40d4a, 0x2c40a95,
31
+ /*2020*/ 0x3004a9d, 0x2c40556, 0x2c60ab5, 0x3002ad6, 0x2c406d2, 0x3006765, 0x2c60ea5, 0x2c40e4a, 0x2fe5656, 0x2c60c9b,
32
+ /*2030*/ 0x2c4055a, 0x300356d, 0x2c60b69, 0x300bf52, 0x2c40752, 0x2c40b25, 0x3016b0b, 0x2c40a4b, 0x2c404ab, 0x30052bb,
33
+ /*2040*/ 0x2c6056d, 0x2c60b69, 0x3002daa, 0x2c40d92, 0x3007ea5, 0x2c40d25, 0x2c40a4d, 0x3015a4d, 0x2c402b6, 0x2c605b5,
34
+ ];
35
+ var BASE_YEAR$1 = 1890;
36
+ var BASE_MONTH$1 = 1;
37
+ var BASE_DAY$1 = 1;
38
+ var MAX_YEAR$1 = 2049;
39
+ var MAX_MONTH$1 = 12;
40
+ var MAX_DAY$1 = 29;
41
+ var SMALL_MONTH_DAY = 29;
42
+ var BIG_MONTH_DAY = 30;
43
+ var totalDaysBeforeYear$1 = {};
44
+ var getYearData = function (year) {
45
+ return LUN_TABLE[year - BASE_YEAR$1];
46
+ };
47
+ /**
48
+ * 해당 월 (평달)의 일 수를 반환합니다.
49
+ * @param year 1890년 ~ 2049년
50
+ * @param month 1월 ~ 12월
51
+ * @returns 월의 일 수 (29 또는 30)
52
+ */
53
+ var getMonthDays$1 = function (year, month) {
54
+ var monthType = (getYearData(year) >> (month - 1)) & 0x1;
55
+ return monthType === 0 ? SMALL_MONTH_DAY : BIG_MONTH_DAY;
56
+ };
57
+ /**
58
+ * 해당 연도의 윤달을 반환합니다.
59
+ * @param year 1890년 ~ 2049년
60
+ * @returns 윤달 월 (1월 ~ 12월), 없으면 0
61
+ */
62
+ var getLeapMonth = function (year) {
63
+ return (getYearData(year) >> 12) & 0xf;
64
+ };
65
+ /**
66
+ * 해당 연도에 윤달이 있는지를 반환합니다.
67
+ * @param year 1890년 ~ 2049년
68
+ * @return 윤달이 있으면 true
69
+ */
70
+ var hasLeapMonth = function (year) {
71
+ return getLeapMonth(year) !== 0;
72
+ };
73
+ /**
74
+ * 해당 월이 윤달인지를 반환합니다.
75
+ * @param year 1890년 ~ 2049년
76
+ * @param month 1월 ~ 12월
77
+ * @returns 윤달이면 true
78
+ */
79
+ var isLeapMonth = function (year, month) {
80
+ return month === getLeapMonth(year);
81
+ };
82
+ /**
83
+ * 해당 월 (윤달)의 일 수를 반환합니다.
84
+ * @param year 1890년 ~ 2049년
85
+ * @param month 1월 ~ 12월
86
+ * @returns 윤달의 일 수 (29 또는 30), 윤달이 아니면 0
87
+ */
88
+ var getLeapMonthDays = function (year, month) {
89
+ if (!isLeapMonth(year, month))
90
+ return 0;
91
+ var monthType = (getYearData(year) >> 16) & 0x1;
92
+ return monthType === 0 ? SMALL_MONTH_DAY : BIG_MONTH_DAY;
93
+ };
94
+ /**
95
+ * 해당 연도의 총 일 수를 반환합니다.
96
+ * @param year 1890년 ~ 2049년
97
+ * @return 해당 연도의 총 일 수
98
+ */
99
+ var getYearDays$1 = function (year) {
100
+ return (getYearData(year) >> 17) & 0x1ff;
101
+ };
102
+ /**
103
+ * 연도별 누적 일 수를 초기에 룩업 테이블로 생성하여
104
+ * O(1)으로 누적 일 수를 가져오게 변환함
105
+ */
106
+ totalDaysBeforeYear$1[BASE_YEAR$1] = 0;
107
+ for (var y$1 = BASE_YEAR$1 + 1; y$1 < MAX_YEAR$1; y$1++) {
108
+ totalDaysBeforeYear$1[y$1] = totalDaysBeforeYear$1[y$1 - 1] + getYearDays$1(y$1 - 1);
109
+ }
110
+ /**
111
+ * 1890년부터 해당 연도 전까지의 누적 일 수를 반환합니다.
112
+ * @param year 1890년 ~ 2049년
113
+ * @return 해당 연도 전까지의 누적 일 수
114
+ */
115
+ var getTotalDaysBeforeYear$1 = function (year) {
116
+ var days = totalDaysBeforeYear$1[year];
117
+ return days;
118
+ };
119
+ /**
120
+ * 해당 연도 내에서 해당 월 (및 윤달 포함) 전까지의 누적 일 수를 반환합니다.
121
+ * @param year 1890년 ~ 2049년
122
+ * @param month 1월 ~ 12월
123
+ * @param isLeapMonth 대상이 윤달이면 true
124
+ * @returns 해당 연도 내, 해당 월 전까지의 누적 일 수
125
+ */
126
+ var getTotalDaysBeforeMonth$1 = function (year, month, isLeapMonth) {
127
+ var days = 0;
128
+ // 해당 월 전까지 윤달을 포함하여 누적
129
+ for (var m = 1; m < month; m++) {
130
+ days += getMonthDays$1(year, m);
131
+ if (m === getLeapMonth(year)) {
132
+ days += getLeapMonthDays(year, m);
133
+ }
134
+ }
135
+ // 대상이 윤달이면, 앞에 있는 평달을 누적
136
+ var leapMonth = getLeapMonth(year);
137
+ if (isLeapMonth && leapMonth === month) {
138
+ days += getMonthDays$1(year, month);
139
+ }
140
+ return days;
141
+ };
142
+ /**
143
+ * 1890년부터 해당 연도, 월, 일 (및 윤달 포함) 까지의 누적 일 수를 반환합니다.
144
+ * @param year 1890년 ~ 2049년
145
+ * @param month 1월 ~ 12월
146
+ * @param day 일자
147
+ * @param isLeapMonth 대상이 윤달이면 true
148
+ * @returns 총 누적 일 수
149
+ */
150
+ var getTotalDays$1 = function (year, month, day, isLeapMonth) {
151
+ var days = getTotalDaysBeforeYear$1(year) + getTotalDaysBeforeMonth$1(year, month, isLeapMonth) + day;
152
+ return days;
153
+ };
154
+ var LunarData = {
155
+ BASE_YEAR: BASE_YEAR$1,
156
+ BASE_MONTH: BASE_MONTH$1,
157
+ BASE_DAY: BASE_DAY$1,
158
+ MAX_YEAR: MAX_YEAR$1,
159
+ MAX_MONTH: MAX_MONTH$1,
160
+ MAX_DAY: MAX_DAY$1,
161
+ getMonthDays: getMonthDays$1,
162
+ getLeapMonth: getLeapMonth,
163
+ hasLeapMonth: hasLeapMonth,
164
+ isLeapMonth: isLeapMonth,
165
+ getLeapMonthDays: getLeapMonthDays,
166
+ getYearDays: getYearDays$1,
167
+ getTotalDaysBeforeYear: getTotalDaysBeforeYear$1,
168
+ getTotalDaysBeforeMonth: getTotalDaysBeforeMonth$1,
169
+ getTotalDays: getTotalDays$1,
170
+ };
171
+
172
+ var MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
173
+ var LEAP_FEBRUARY_DAY = 29;
174
+ var YEAR_DAY = 365;
175
+ var LEAP_YEAR_DAY = 366;
176
+ var BASE_YEAR = 1890;
177
+ var BASE_MONTH = 1;
178
+ var BASE_DAY = 21;
179
+ var MAX_YEAR = 2050;
180
+ var MAX_MONTH = 1;
181
+ var MAX_DAY = 22;
182
+ var totalDaysBeforeYear = {};
183
+ var isLeapYear = function (year) {
184
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
185
+ };
186
+ var getMonthDays = function (year, month) {
187
+ var day = month == 2 && isLeapYear(year) ? LEAP_FEBRUARY_DAY : MONTH_DAYS[month - 1];
188
+ return day;
189
+ };
190
+ var getYearDays = function (year) {
191
+ var day = isLeapYear(year) ? LEAP_YEAR_DAY : YEAR_DAY;
192
+ return day;
193
+ };
194
+ /**
195
+ * 연도별 누적 일 수를 초기에 룩업 테이블로 생성하여
196
+ * O(1)으로 누적 일 수를 가져오게 변환함
197
+ */
198
+ totalDaysBeforeYear[BASE_YEAR] = 0;
199
+ for (var y = BASE_YEAR + 1; y < MAX_YEAR; y++) {
200
+ totalDaysBeforeYear[y] = totalDaysBeforeYear[y - 1] + getYearDays(y - 1);
201
+ }
202
+ var getTotalDaysBeforeYear = function (year) {
203
+ var day = totalDaysBeforeYear[year];
204
+ return day;
205
+ };
206
+ var getTotalDaysBeforeMonth = function (year, month) {
207
+ var day = 0;
208
+ for (var m = 1; m < month; m++) {
209
+ day += getMonthDays(year, m);
210
+ }
211
+ return day;
212
+ };
213
+ var getTotalDays = function (year, month, day) {
214
+ var days = getTotalDaysBeforeYear(year) + getTotalDaysBeforeMonth(year, month) + day;
215
+ return days;
216
+ };
217
+ var SolarData = {
218
+ BASE_YEAR: BASE_YEAR,
219
+ BASE_MONTH: BASE_MONTH,
220
+ BASE_DAY: BASE_DAY,
221
+ MAX_YEAR: MAX_YEAR,
222
+ MAX_MONTH: MAX_MONTH,
223
+ MAX_DAY: MAX_DAY,
224
+ isLeapYear: isLeapYear,
225
+ getMonthDays: getMonthDays,
226
+ getYearDays: getYearDays,
227
+ getTotalDays: getTotalDays,
228
+ };
229
+
230
+ var SOLAR_LUNAR_DAY_DIFF = 20;
231
+ var toLunar = function (solYear, solMonth, solDay) {
232
+ var year = LunarData.BASE_YEAR;
233
+ var month = LunarData.BASE_MONTH;
234
+ var day = LunarData.BASE_DAY + SolarData.getTotalDays(solYear, solMonth, solDay) - SOLAR_LUNAR_DAY_DIFF - 1;
235
+ var yearDays = LunarData.getYearDays(year);
236
+ while (day > yearDays) {
237
+ year++;
238
+ day -= yearDays;
239
+ yearDays = LunarData.getYearDays(year);
240
+ }
241
+ var isLeapMonth = false;
242
+ var leapMonth = LunarData.getLeapMonth(year);
243
+ var monthDays = LunarData.getMonthDays(year, month);
244
+ while (day > monthDays) {
245
+ day -= monthDays;
246
+ isLeapMonth = false;
247
+ if (month === leapMonth) {
248
+ leapMonth = 0;
249
+ monthDays = LunarData.getLeapMonthDays(year, month);
250
+ isLeapMonth = true;
251
+ continue;
252
+ }
253
+ month++;
254
+ if (month > 12) {
255
+ month = 1;
256
+ year++;
257
+ leapMonth = LunarData.getLeapMonth(year);
258
+ }
259
+ monthDays = LunarData.getMonthDays(year, month);
260
+ }
261
+ return { year: year, month: month, day: day, isLeapMonth: isLeapMonth };
262
+ };
263
+ var toSolar = function (lunYear, lunMonth, lunDay, isLeapMonth) {
264
+ var year = SolarData.BASE_YEAR;
265
+ var month = SolarData.BASE_MONTH;
266
+ var day = SolarData.BASE_DAY + LunarData.getTotalDays(lunYear, lunMonth, lunDay, isLeapMonth) - 1;
267
+ var yearDays = SolarData.getYearDays(year);
268
+ while (day > yearDays) {
269
+ day -= yearDays;
270
+ year++;
271
+ yearDays = SolarData.getYearDays(year);
272
+ }
273
+ var monthDays = SolarData.getMonthDays(year, month);
274
+ while (day > monthDays) {
275
+ day -= monthDays;
276
+ month++;
277
+ if (month > 12) {
278
+ month = 1;
279
+ year++;
280
+ }
281
+ monthDays = SolarData.getMonthDays(year, month);
282
+ }
283
+ return { year: year, month: month, day: day };
284
+ };
285
+
286
+ var korLunar = { toLunar: toLunar, toSolar: toSolar };
287
+
288
+ exports["default"] = korLunar;
289
+ exports.toLunar = toLunar;
290
+ exports.toSolar = toSolar;
291
+ //# sourceMappingURL=kor-lunar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kor-lunar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ var korLunar=function(r){"use strict";var n=[50342582,46534058,50360036,46403236,46402890,50222421,46533271,46400854,50345309,46533333,50367442,46401362,46534309,50223914,46401099,46533275,50416294,46400874,46533465,50342826,46401362,50359717,46402341,46402123,50354523,46533293,46400874,50341301,46533545,50363858,46402962,46402853,50355501,46401878,46400181,50481885,46401236,46534057,50343626,46403218,50226854,46400807,46533207,50420054,46533338,46401236,50411345,46401353,50428691,46402195,46400811,50423067,46532973,46533482,50417060,46402468,46402377,50343243,46402197,50363051,46400813,46533293,50420394,46534066,46402980,50413217,46402890,50367893,46402198,46400854,50357621,46533333,46401234,50349909,46534309,46403146,50214478,46533275,50363094,46400874,46533465,50355122,46401362,46401317,50350891,46402123,50366891,46400173,46531947,50423209,46534057,46402962,50351509,46402853,50376269,46402134,46400182,50490093,46401236,46534057,50355922,46403218,46402854,50214190,46533207,50366902,46533466,46401236,50354025,46401353,46401171,50350743,46400811,46533211,50342574,46400362,50494933,46402468,46402377,50355539,46402197,46400813,50410797,46533293,50371498,46400978,46534053,50355882,46402890,46402197,50350749,46400854,46533301,50342614,46401234,50358117,46534309,46403146,50222678,46533787,46400858,50345325,46533481,50380626,46401362,46402341,50424587,46402123,46400683,50352827,46531949,46533481,50343338,46402962,50364069,46402853,46402125,50420301,46400182,46532021],t=1890,u={},o=function(r){return n[r-t]},e=function(r,n){return 0===(o(r)>>n-1&1)?29:30},f=function(r){return o(r)>>12&15},a=function(r,n){return n===f(r)},i=function(r,n){return a(r,n)?0===(o(r)>>16&1)?29:30:0},c=function(r){return o(r)>>17&511};u[1890]=0;for(var v=1891;v<2049;v++)u[v]=u[v-1]+c(v-1);var d=function(r){return u[r]},l=function(r,n,t){for(var u=0,o=1;o<n;o++)u+=e(r,o),o===f(r)&&(u+=i(r,o));var a=f(r);return t&&a===n&&(u+=e(r,n)),u},y=t,s=1,L=1,h=e,m=f,p=i,M=c,S=function(r,n,t,u){return d(r)+l(r,n,u)+t},_=[31,28,31,30,31,30,31,31,30,31,30,31],b=1890,j={},k=function(r){return r%4==0&&r%100!=0||r%400==0},O=function(r,n){return 2==n&&k(r)?29:_[n-1]},P=function(r){return k(r)?366:365};j[1890]=0;for(var g=1891;g<2050;g++)j[g]=j[g-1]+P(g-1);var q=b,w=1,x=21,z=O,A=P,B=function(r,n,t){var u=function(r){return j[r]}(r)+function(r,n){for(var t=0,u=1;u<n;u++)t+=O(r,u);return t}(r,n)+t;return u},C=function(r,n,t){for(var u=y,o=s,e=L+B(r,n,t)-20-1,f=M(u);e>f;)u++,e-=f,f=M(u);for(var a=!1,i=m(u),c=h(u,o);e>c;)e-=c,a=!1,o!==i?(++o>12&&(o=1,u++,i=m(u)),c=h(u,o)):(i=0,c=p(u,o),a=!0);return{year:u,month:o,day:e,isLeapMonth:a}},D=function(r,n,t,u){for(var o=q,e=w,f=x+S(r,n,t,u)-1,a=A(o);f>a;)f-=a,o++,a=A(o);for(var i=z(o,e);f>i;)f-=i,++e>12&&(e=1,o++),i=z(o,e);return{year:o,month:e,day:f}},E={toLunar:C,toSolar:D};return r.default=E,r.toLunar=C,r.toSolar=D,Object.defineProperty(r,"__esModule",{value:!0}),r}({});
2
+ //# sourceMappingURL=kor-lunar.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kor-lunar.min.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ export declare const LunarData: {
2
+ BASE_YEAR: number;
3
+ BASE_MONTH: number;
4
+ BASE_DAY: number;
5
+ MAX_YEAR: number;
6
+ MAX_MONTH: number;
7
+ MAX_DAY: number;
8
+ getMonthDays: (year: number, month: number) => number;
9
+ getLeapMonth: (year: number) => number;
10
+ hasLeapMonth: (year: number) => boolean;
11
+ isLeapMonth: (year: number, month: number) => boolean;
12
+ getLeapMonthDays: (year: number, month: number) => number;
13
+ getYearDays: (year: number) => number;
14
+ getTotalDaysBeforeYear: (year: number) => number;
15
+ getTotalDaysBeforeMonth: (year: number, month: number, isLeapMonth: boolean) => number;
16
+ getTotalDays: (year: number, month: number, day: number, isLeapMonth: boolean) => number;
17
+ };
@@ -0,0 +1,12 @@
1
+ export declare const SolarData: {
2
+ BASE_YEAR: number;
3
+ BASE_MONTH: number;
4
+ BASE_DAY: number;
5
+ MAX_YEAR: number;
6
+ MAX_MONTH: number;
7
+ MAX_DAY: number;
8
+ isLeapYear: (year: number) => boolean;
9
+ getMonthDays: (year: number, month: number) => number;
10
+ getYearDays: (year: number) => number;
11
+ getTotalDays: (year: number, month: number, day: number) => number;
12
+ };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "kor-lunar",
3
+ "version": "1.0.2",
4
+ "description": "한국 음력 변환 유틸 / Korean lunar calendar converter",
5
+ "main": "dist/kor-lunar.js",
6
+ "module": "dist/kor-lunar.esm.js",
7
+ "types": "dist/kor-lunar.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/kor-lunar.d.ts",
11
+ "import": "./dist/kor-lunar.esm.js",
12
+ "require": "./dist/kor-lunar.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist/"
17
+ ],
18
+ "scripts": {
19
+ "build": "rollup -c",
20
+ "postversion": "git push && git push --tags"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/kahyou22/kor-lunar-js.git"
25
+ },
26
+ "keywords": [
27
+ "한국",
28
+ "음력",
29
+ "달력",
30
+ "korean",
31
+ "lunar",
32
+ "calendar"
33
+ ],
34
+ "author": "kahyou",
35
+ "license": "MIT",
36
+ "bugs": {
37
+ "url": "https://github.com/kahyou22/kor-lunar-js/issues"
38
+ },
39
+ "homepage": "https://github.com/kahyou22/kor-lunar-js#readme",
40
+ "devDependencies": {
41
+ "@rollup/plugin-commonjs": "^28.0.3",
42
+ "@rollup/plugin-node-resolve": "^16.0.1",
43
+ "rollup": "^2.79.2",
44
+ "rollup-plugin-terser": "^7.0.2",
45
+ "rollup-plugin-typescript2": "^0.36.0",
46
+ "typescript": "^5.8.3"
47
+ }
48
+ }