@sanguogege/calendar 1.0.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/index.html +18 -0
- package/package.json +22 -0
- package/src/core/index.ts +261 -0
- package/src/data/Calendar.ts +598 -0
- package/src/data/fastival.json +637 -0
- package/src/data/rest.json +86 -0
- package/src/utils/LunarFunction.ts +160 -0
- package/src/utils/SetFestival.ts +62 -0
- package/src/utils/SetRest.ts +50 -0
- package/src/utils/SolarFunction.ts +129 -0
- package/src/utils/Switch.ts +261 -0
- package/tsconfig.json +23 -0
- package/vite.config.js +14 -0
package/index.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + TS</title>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app"></div>
|
|
12
|
+
</body>
|
|
13
|
+
<script src="./dist/index.umd.cjs"></script>
|
|
14
|
+
<script>
|
|
15
|
+
console.log(calendar);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sanguogege/calendar",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"日历",
|
|
6
|
+
"农历",
|
|
7
|
+
"阳历",
|
|
8
|
+
"calendar"
|
|
9
|
+
],
|
|
10
|
+
"description": "ts版本的日历生成器 LTS",
|
|
11
|
+
"author": "sanguogege",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "vite",
|
|
15
|
+
"build": "tsc && vite build",
|
|
16
|
+
"preview": "vite preview"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.0.2",
|
|
20
|
+
"vite": "^4.3.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lYearDays,
|
|
3
|
+
leapMonth,
|
|
4
|
+
leapDays,
|
|
5
|
+
lMonthDays,
|
|
6
|
+
toGanZhiYear,
|
|
7
|
+
toGanZhi,
|
|
8
|
+
toHourGanZhi,
|
|
9
|
+
toChinaMonth,
|
|
10
|
+
toChinaDay,
|
|
11
|
+
getSolarTerm,
|
|
12
|
+
} from "../utils/LunarFunction";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
toAstro,
|
|
16
|
+
getTerm,
|
|
17
|
+
getAnimal,
|
|
18
|
+
solarDays,
|
|
19
|
+
solarFirstWeek,
|
|
20
|
+
toChinaNum,
|
|
21
|
+
} from "../utils/SolarFunction";
|
|
22
|
+
|
|
23
|
+
import { RestDay } from "../utils/SetRest";
|
|
24
|
+
import { FestivalDay } from "../utils/SetFestival";
|
|
25
|
+
|
|
26
|
+
const solar2lunar = function (y: number, m: number, d: number): object {
|
|
27
|
+
//未传参获得当天
|
|
28
|
+
let objDate: Date;
|
|
29
|
+
if (!y) {
|
|
30
|
+
objDate = new Date();
|
|
31
|
+
} else {
|
|
32
|
+
objDate = new Date(y, m - 1, d);
|
|
33
|
+
}
|
|
34
|
+
let i: number,
|
|
35
|
+
leap: number = 0,
|
|
36
|
+
temp: number = 0;
|
|
37
|
+
//修正ymd参数
|
|
38
|
+
(y = objDate.getFullYear()),
|
|
39
|
+
(m = objDate.getMonth() + 1),
|
|
40
|
+
(d = objDate.getDate());
|
|
41
|
+
let offset: number =
|
|
42
|
+
(Date.UTC(
|
|
43
|
+
objDate.getFullYear(),
|
|
44
|
+
objDate.getMonth(),
|
|
45
|
+
objDate.getDate()
|
|
46
|
+
) -
|
|
47
|
+
Date.UTC(1900, 0, 31)) /
|
|
48
|
+
86400000;
|
|
49
|
+
for (i = 1900; i < 2101 && offset > 0; i++) {
|
|
50
|
+
temp = lYearDays(i);
|
|
51
|
+
offset -= temp;
|
|
52
|
+
}
|
|
53
|
+
if (offset < 0) {
|
|
54
|
+
offset += temp;
|
|
55
|
+
i--;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//是否今天
|
|
59
|
+
let isTodayObj: Date = new Date(),
|
|
60
|
+
isToday: boolean = false;
|
|
61
|
+
if (
|
|
62
|
+
isTodayObj.getFullYear() == y &&
|
|
63
|
+
isTodayObj.getMonth() + 1 == m &&
|
|
64
|
+
isTodayObj.getDate() == d
|
|
65
|
+
) {
|
|
66
|
+
isToday = true;
|
|
67
|
+
}
|
|
68
|
+
//星期几
|
|
69
|
+
var nWeek: number = objDate.getDay(),
|
|
70
|
+
cWeek: string = toChinaNum(nWeek);
|
|
71
|
+
//数字表示周几顺应天朝周一开始的惯例
|
|
72
|
+
if (nWeek == 0) {
|
|
73
|
+
nWeek = 7;
|
|
74
|
+
}
|
|
75
|
+
//农历年
|
|
76
|
+
let year: number = i;
|
|
77
|
+
leap = leapMonth(i); //闰哪个月
|
|
78
|
+
let isLeap = false;
|
|
79
|
+
|
|
80
|
+
//效验闰月
|
|
81
|
+
for (i = 1; i < 13 && offset > 0; i++) {
|
|
82
|
+
//闰月
|
|
83
|
+
if (leap > 0 && i == leap + 1 && isLeap == false) {
|
|
84
|
+
--i;
|
|
85
|
+
isLeap = true;
|
|
86
|
+
temp = leapDays(year); //计算农历闰月天数
|
|
87
|
+
} else {
|
|
88
|
+
temp = lMonthDays(year, i); //计算农历普通月天数
|
|
89
|
+
}
|
|
90
|
+
//解除闰月
|
|
91
|
+
if (isLeap == true && i == leap + 1) {
|
|
92
|
+
isLeap = false;
|
|
93
|
+
}
|
|
94
|
+
offset -= temp;
|
|
95
|
+
}
|
|
96
|
+
// 闰月导致数组下标重叠取反
|
|
97
|
+
if (offset == 0 && leap > 0 && i == leap + 1) {
|
|
98
|
+
if (isLeap) {
|
|
99
|
+
isLeap = false;
|
|
100
|
+
} else {
|
|
101
|
+
isLeap = true;
|
|
102
|
+
--i;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (offset < 0) {
|
|
106
|
+
offset += temp;
|
|
107
|
+
--i;
|
|
108
|
+
}
|
|
109
|
+
//农历月
|
|
110
|
+
let month: number = i;
|
|
111
|
+
//农历日
|
|
112
|
+
let day: number = offset + 1;
|
|
113
|
+
//天干地支处理
|
|
114
|
+
let sm: number = m - 1;
|
|
115
|
+
let gzY: string = toGanZhiYear(year);
|
|
116
|
+
|
|
117
|
+
// 当月的两个节气
|
|
118
|
+
let firstNode: number = getTerm(y, m * 2 - 1); //返回当月「节」为几日开始
|
|
119
|
+
let secondNode: number = getTerm(y, m * 2); //返回当月「节」为几日开始
|
|
120
|
+
|
|
121
|
+
// 依据12节气修正干支月
|
|
122
|
+
let gzM: string = toGanZhi((y - 1900) * 12 + m + 11);
|
|
123
|
+
if (d >= firstNode) {
|
|
124
|
+
gzM = toGanZhi((y - 1900) * 12 + m + 12);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//传入的日期的节气与否,有则值,没有则为null
|
|
128
|
+
let Term: any = null;
|
|
129
|
+
if (firstNode == d) {
|
|
130
|
+
Term = getSolarTerm(m * 2 - 2);
|
|
131
|
+
}
|
|
132
|
+
if (secondNode == d) {
|
|
133
|
+
Term = getSolarTerm(m * 2 - 1);
|
|
134
|
+
}
|
|
135
|
+
//日柱 当月一日与 1900/1/1 相差天数
|
|
136
|
+
let dayCyclical: number =
|
|
137
|
+
Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10;
|
|
138
|
+
let gzD: string = toGanZhi(dayCyclical + d - 1);
|
|
139
|
+
|
|
140
|
+
// 二十四小时对应的天干地支
|
|
141
|
+
let gzH = toHourGanZhi(dayCyclical + d - 1);
|
|
142
|
+
|
|
143
|
+
//该日期所属的星座
|
|
144
|
+
let astro: string = toAstro(m, d);
|
|
145
|
+
// 设置公里节日
|
|
146
|
+
const GAll = FestivalDay(m, d, calendar.setFestival);
|
|
147
|
+
const NAll = FestivalDay(month, day, calendar.setFestival, false);
|
|
148
|
+
let Gljr = GAll.FDays;
|
|
149
|
+
let Nljr = NAll.FDays;
|
|
150
|
+
calendar.Festival = {
|
|
151
|
+
sFtv: GAll.Festival,
|
|
152
|
+
lFtv: NAll.Festival,
|
|
153
|
+
};
|
|
154
|
+
let XiuBox = RestDay(y, m, d, calendar.setRest);
|
|
155
|
+
calendar.Rest = XiuBox.newRest;
|
|
156
|
+
// 用于设置上个月
|
|
157
|
+
return {
|
|
158
|
+
Xiu: XiuBox.Xiu,
|
|
159
|
+
Ban: XiuBox.Ban,
|
|
160
|
+
Gljr: Gljr,
|
|
161
|
+
Nljr: Nljr,
|
|
162
|
+
lYear: year,
|
|
163
|
+
lMonth: month,
|
|
164
|
+
lDay: day,
|
|
165
|
+
Animal: getAnimal(year),
|
|
166
|
+
LMonthCn: (isLeap ? "\u95f0" : "") + toChinaMonth(month),
|
|
167
|
+
LDayCn: toChinaDay(day),
|
|
168
|
+
cYear: y,
|
|
169
|
+
cMonth: m,
|
|
170
|
+
cDay: d,
|
|
171
|
+
gzYear: gzY,
|
|
172
|
+
gzMonth: gzM,
|
|
173
|
+
gzDay: gzD,
|
|
174
|
+
gzHour: gzH,
|
|
175
|
+
isToday: isToday,
|
|
176
|
+
isLeap: isLeap,
|
|
177
|
+
nWeek: nWeek,
|
|
178
|
+
ncWeek: "\u661f\u671f" + cWeek,
|
|
179
|
+
Term: Term,
|
|
180
|
+
astro: astro,
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const lunar2solar = function (
|
|
185
|
+
y: number,
|
|
186
|
+
m: number,
|
|
187
|
+
d: number,
|
|
188
|
+
isLeapMonth: boolean
|
|
189
|
+
): any {
|
|
190
|
+
//参数区间1900.1.31~2100.12.1
|
|
191
|
+
isLeapMonth = !!isLeapMonth;
|
|
192
|
+
let leapM: any = leapMonth(y);
|
|
193
|
+
if (isLeapMonth && leapM != m) {
|
|
194
|
+
return -1;
|
|
195
|
+
} //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
|
|
196
|
+
if ((y == 2100 && m == 12 && d > 1) || (y == 1900 && m == 1 && d < 31)) {
|
|
197
|
+
return -1;
|
|
198
|
+
} //超出了最大极限值
|
|
199
|
+
let day: number = lMonthDays(y, m);
|
|
200
|
+
let _day: number = day;
|
|
201
|
+
//bugFix 2016-9-25
|
|
202
|
+
//if month is leap, _day use leapDays method
|
|
203
|
+
if (isLeapMonth) {
|
|
204
|
+
_day = leapDays(y);
|
|
205
|
+
}
|
|
206
|
+
if (y < 1900 || y > 2100 || d > _day) {
|
|
207
|
+
return -1;
|
|
208
|
+
} //参数合法性效验
|
|
209
|
+
|
|
210
|
+
//计算农历的时间差
|
|
211
|
+
let offset: number = 0;
|
|
212
|
+
for (let i = 1900; i < y; i++) {
|
|
213
|
+
offset += lYearDays(i);
|
|
214
|
+
}
|
|
215
|
+
let leap: number = 0,
|
|
216
|
+
isAdd: boolean = false;
|
|
217
|
+
for (let i = 1; i < m; i++) {
|
|
218
|
+
leap = leapMonth(y);
|
|
219
|
+
if (!isAdd) {
|
|
220
|
+
//处理闰月
|
|
221
|
+
if (leap <= i && leap > 0) {
|
|
222
|
+
offset += leapDays(y);
|
|
223
|
+
isAdd = true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
offset += lMonthDays(y, i);
|
|
227
|
+
}
|
|
228
|
+
//转换闰月农历 需补充该年闰月的前一个月的时差
|
|
229
|
+
if (isLeapMonth) {
|
|
230
|
+
offset += day;
|
|
231
|
+
}
|
|
232
|
+
//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
|
|
233
|
+
let stmap: number = Date.UTC(1900, 1, 30, 0, 0, 0);
|
|
234
|
+
let calObj: Date = new Date((offset + d - 31) * 86400000 + stmap);
|
|
235
|
+
let cY: number = calObj.getUTCFullYear();
|
|
236
|
+
let cM: number = calObj.getUTCMonth() + 1;
|
|
237
|
+
let cD: number = calObj.getUTCDate();
|
|
238
|
+
|
|
239
|
+
return solar2lunar(cY, cM, cD);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const calendar = {
|
|
243
|
+
setRest: {},
|
|
244
|
+
Rest: {},
|
|
245
|
+
setFestival: {},
|
|
246
|
+
Festival: {},
|
|
247
|
+
lYearDays,
|
|
248
|
+
leapMonth,
|
|
249
|
+
leapDays,
|
|
250
|
+
lMonthDays,
|
|
251
|
+
toChinaMonth,
|
|
252
|
+
toChinaDay,
|
|
253
|
+
solarDays,
|
|
254
|
+
solarFirstWeek,
|
|
255
|
+
toAstro,
|
|
256
|
+
getAnimal,
|
|
257
|
+
solar2lunar,
|
|
258
|
+
lunar2solar,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export default calendar;
|