sard-uniapp 1.17.1 → 1.18.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/CHANGELOG.md +11 -0
- package/components/button/button.vue +1 -1
- package/components/calendar-month/calendar-month.vue +8 -8
- package/components/config/index.d.ts +1 -0
- package/components/config/index.js +1 -0
- package/components/datetime-picker/common.d.ts +7 -3
- package/components/datetime-picker/common.js +181 -9
- package/components/datetime-picker/datetime-picker.d.ts +1 -0
- package/components/datetime-picker/datetime-picker.vue +116 -20
- package/components/datetime-picker-input/common.d.ts +1 -0
- package/components/datetime-picker-input/datetime-picker-input.d.ts +1 -0
- package/components/datetime-picker-input/datetime-picker-input.vue +2 -0
- package/components/datetime-picker-popout/common.d.ts +1 -0
- package/components/datetime-picker-popout/datetime-picker-popout.d.ts +1 -0
- package/components/datetime-picker-popout/datetime-picker-popout.vue +2 -0
- package/components/datetime-range-picker/datetime-range-picker.vue +1 -0
- package/components/datetime-range-picker-input/datetime-range-picker-input.vue +1 -0
- package/components/datetime-range-picker-popout/datetime-range-picker-popout.vue +1 -0
- package/components/dropdown/common.d.ts +2 -1
- package/components/dropdown-item/dropdown-item.d.ts +5 -7
- package/components/dropdown-item/dropdown-item.vue +3 -1
- package/components/empty/empty.vue +1 -1
- package/components/fab/fab.vue +1 -1
- package/components/grid-item/grid-item.vue +1 -1
- package/components/icon/icon.vue +9 -4
- package/components/list-item/list-item.vue +1 -1
- package/components/menu-item/menu-item.vue +1 -1
- package/components/navbar-item/navbar-item.vue +1 -1
- package/components/rate/rate.vue +2 -2
- package/components/result/result.vue +1 -1
- package/components/share-sheet/share-sheet.vue +1 -1
- package/components/step/step.vue +1 -1
- package/components/tabbar-item/tabbar-item.vue +1 -5
- package/components/timeline-item/timeline-item.vue +1 -5
- package/package.json +1 -1
- package/utils/date.d.ts +33 -3
- package/utils/date.js +209 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# [1.18.0](https://github.com/sutras/sard-uniapp/compare/v1.17.1...v1.18.0) (2025-06-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* datetime-picker 组件新增农历类型 ([7b0f305](https://github.com/sutras/sard-uniapp/commit/7b0f305f57ff43f322ef4a398f95415a5a9e01e0))
|
|
7
|
+
* dropdown-item 组件新增显隐动画相关事件 ([83e8c52](https://github.com/sutras/sard-uniapp/commit/83e8c52e996bdc4901ea446b30d9273d0e5e956d))
|
|
8
|
+
* icon支持冒号分隔符名称属性 ([7ffcd90](https://github.com/sutras/sard-uniapp/commit/7ffcd9056e006cc353aadf5cb2831edde9515719))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
1
12
|
## [1.17.1](https://github.com/sutras/sard-uniapp/compare/v1.17.0...v1.17.1) (2025-05-30)
|
|
2
13
|
|
|
3
14
|
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
import { defineComponent as _defineComponent } from "vue";
|
|
35
35
|
import { computed } from "vue";
|
|
36
36
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
getMonthDays,
|
|
38
|
+
getOffsetDaysFromMonthStart,
|
|
39
|
+
getWeekOfMonthStart,
|
|
40
40
|
getPadStartDays,
|
|
41
41
|
getPadEndDays,
|
|
42
42
|
toDateNumber,
|
|
@@ -72,11 +72,11 @@ export default _defineComponent({
|
|
|
72
72
|
const props = __props;
|
|
73
73
|
const emit = __emit;
|
|
74
74
|
const days = computed(() => {
|
|
75
|
-
return
|
|
75
|
+
return getMonthDays(props.year, props.month + 1);
|
|
76
76
|
});
|
|
77
77
|
const offsetDays = computed(() => {
|
|
78
|
-
return
|
|
79
|
-
|
|
78
|
+
return getOffsetDaysFromMonthStart(
|
|
79
|
+
getWeekOfMonthStart(props.year, props.month + 1),
|
|
80
80
|
props.weekStartsOn
|
|
81
81
|
);
|
|
82
82
|
});
|
|
@@ -87,12 +87,12 @@ export default _defineComponent({
|
|
|
87
87
|
}
|
|
88
88
|
const padStartDays = getPadStartDays(
|
|
89
89
|
props.year,
|
|
90
|
-
props.month,
|
|
90
|
+
props.month + 1,
|
|
91
91
|
offsetDays.value
|
|
92
92
|
);
|
|
93
93
|
const padEndDays = getPadEndDays(
|
|
94
94
|
props.year,
|
|
95
|
-
props.month,
|
|
95
|
+
props.month + 1,
|
|
96
96
|
42 - offsetDays.value - days.value
|
|
97
97
|
);
|
|
98
98
|
return [...padStartDays, ...currentDays, ...padEndDays];
|
|
@@ -4,6 +4,7 @@ export interface DatetimePickerProps {
|
|
|
4
4
|
rootStyle?: StyleValue;
|
|
5
5
|
rootClass?: string;
|
|
6
6
|
type?: string;
|
|
7
|
+
calendar?: 'solar' | 'lunar';
|
|
7
8
|
min?: Date | string;
|
|
8
9
|
max?: Date | string;
|
|
9
10
|
modelValue?: Date | string;
|
|
@@ -13,6 +14,7 @@ export interface DatetimePickerProps {
|
|
|
13
14
|
}
|
|
14
15
|
export declare const defaultDatetimePickerProps: {
|
|
15
16
|
type: string;
|
|
17
|
+
calendar: "solar";
|
|
16
18
|
};
|
|
17
19
|
export interface DatetimePickerSlots extends PickerSlots {
|
|
18
20
|
}
|
|
@@ -42,8 +44,10 @@ interface Strategies {
|
|
|
42
44
|
}
|
|
43
45
|
export declare const strategies: Strategies;
|
|
44
46
|
export declare const letterArray: DatetimeLetter[];
|
|
45
|
-
export declare function getBoundaryValue(isMax: boolean, endDate: Date, currentDate: Date): number[];
|
|
46
|
-
export declare function
|
|
47
|
-
export declare
|
|
47
|
+
export declare function getBoundaryValue(calendar: 'solar' | 'lunar', isMax: boolean, endDate: Date, currentDate: Date): number[];
|
|
48
|
+
export declare function correctSolarDate(date: DateEvery, minDate: Date, maxDate: Date): void;
|
|
49
|
+
export declare function correctLunarDate(date: DateEvery, minDate: Date, maxDate: Date): void;
|
|
50
|
+
export declare function correctDate(calendar: 'solar' | 'lunar', date: DateEvery, minDate: Date, maxDate: Date): void;
|
|
51
|
+
export declare const getColumnData: (calendar: "solar" | "lunar", min: number, max: number, length: number, letter: DatetimeLetter, currentDate: Date, translate: (...args: any[]) => any, filter?: (letter: DatetimeLetter, value: number, date: Date, index: number) => boolean, formatter?: (letter: DatetimeLetter, option: DatetimeColumnOption, date: Date, index: number) => string | void | undefined) => DatetimeColumnOption[];
|
|
48
52
|
export declare function getInitialValue(minDate: Date, maxDate: Date): Date;
|
|
49
53
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getLunarDayName, getLunarLeapMonth, getLunarLeapMonthDays, getLunarMonthDays, getLunarMonthName, getMonthDays, minmax, solarToLunar, } from '../../utils';
|
|
2
2
|
import { defaultConfig } from '../config';
|
|
3
3
|
export const defaultDatetimePickerProps = defaultConfig.datetimePicker;
|
|
4
4
|
export const getMinDate = () => {
|
|
@@ -16,7 +16,7 @@ export const strategies = {
|
|
|
16
16
|
s: [5, 2, 0, 59, (d) => d.getSeconds(), (d, val) => d.setSeconds(val)],
|
|
17
17
|
};
|
|
18
18
|
export const letterArray = ['y', 'M', 'd', 'h', 'm', 's'];
|
|
19
|
-
|
|
19
|
+
function getSolarBoundaryValue(isMax, endDate, currentDate) {
|
|
20
20
|
const currEvery = [endDate.getFullYear()];
|
|
21
21
|
const minOrMaxIndex = isMax ? 3 : 2;
|
|
22
22
|
let aside = true;
|
|
@@ -25,7 +25,7 @@ export function getBoundaryValue(isMax, endDate, currentDate) {
|
|
|
25
25
|
const strategy = strategies[letter];
|
|
26
26
|
let minOrMax = strategy[minOrMaxIndex];
|
|
27
27
|
if (isMax && letter === 'd') {
|
|
28
|
-
minOrMax =
|
|
28
|
+
minOrMax = getMonthDays(currentDate.getFullYear(), currentDate.getMonth() + 1);
|
|
29
29
|
}
|
|
30
30
|
aside = aside && currEvery[index] === prevGetter(currentDate);
|
|
31
31
|
currEvery[index + 1] = aside ? strategy[4](endDate) : minOrMax;
|
|
@@ -33,7 +33,56 @@ export function getBoundaryValue(isMax, endDate, currentDate) {
|
|
|
33
33
|
});
|
|
34
34
|
return currEvery;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
function getLunarBoundaryValue(isMax, endDate, currentDate) {
|
|
37
|
+
const lunarDate = solarToLunar(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate());
|
|
38
|
+
const lunarEndDate = solarToLunar(endDate.getFullYear(), endDate.getMonth() + 1, endDate.getDate());
|
|
39
|
+
const currEvery = [lunarEndDate.year];
|
|
40
|
+
const minOrMaxIndex = isMax ? 3 : 2;
|
|
41
|
+
let aside = true;
|
|
42
|
+
let prevGetter = strategies.y[4];
|
|
43
|
+
letterArray.slice(1).forEach((letter, index) => {
|
|
44
|
+
const prevValue = currEvery[index];
|
|
45
|
+
const strategy = strategies[letter];
|
|
46
|
+
const currGetter = strategy[4];
|
|
47
|
+
let minOrMax = strategy[minOrMaxIndex];
|
|
48
|
+
if (isMax && letter === 'd') {
|
|
49
|
+
minOrMax =
|
|
50
|
+
lunarDate.month < 0
|
|
51
|
+
? getLunarLeapMonthDays(lunarDate.year)
|
|
52
|
+
: getLunarMonthDays(lunarDate.year, lunarDate.month);
|
|
53
|
+
}
|
|
54
|
+
let asideValue = 0;
|
|
55
|
+
if (aside) {
|
|
56
|
+
if (letter === 'M') {
|
|
57
|
+
aside = lunarDate.year === prevValue;
|
|
58
|
+
if (aside) {
|
|
59
|
+
asideValue = lunarEndDate.month;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (letter === 'd') {
|
|
63
|
+
aside = lunarDate.month === prevValue;
|
|
64
|
+
if (aside) {
|
|
65
|
+
asideValue = lunarEndDate.day;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
aside = prevGetter(currentDate) === prevValue;
|
|
70
|
+
if (aside) {
|
|
71
|
+
asideValue = currGetter(currentDate);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
currEvery[index + 1] = aside ? asideValue : minOrMax;
|
|
76
|
+
prevGetter = currGetter;
|
|
77
|
+
});
|
|
78
|
+
return currEvery;
|
|
79
|
+
}
|
|
80
|
+
export function getBoundaryValue(calendar, isMax, endDate, currentDate) {
|
|
81
|
+
return calendar === 'solar'
|
|
82
|
+
? getSolarBoundaryValue(isMax, endDate, currentDate)
|
|
83
|
+
: getLunarBoundaryValue(isMax, endDate, currentDate);
|
|
84
|
+
}
|
|
85
|
+
export function correctSolarDate(date, minDate, maxDate) {
|
|
37
86
|
let minAside = true;
|
|
38
87
|
let maxAside = true;
|
|
39
88
|
let prevGetter = strategies.y[4];
|
|
@@ -42,7 +91,7 @@ export function correctDate(date, minDate, maxDate) {
|
|
|
42
91
|
let minValue = strategy[2];
|
|
43
92
|
let maxValue = strategy[3];
|
|
44
93
|
if (letter === 'd') {
|
|
45
|
-
maxValue =
|
|
94
|
+
maxValue = getMonthDays(date[0], date[1]);
|
|
46
95
|
}
|
|
47
96
|
const currGetter = strategy[4];
|
|
48
97
|
if ((minAside = minAside && prevGetter(minDate) === date[index])) {
|
|
@@ -55,18 +104,141 @@ export function correctDate(date, minDate, maxDate) {
|
|
|
55
104
|
prevGetter = currGetter;
|
|
56
105
|
});
|
|
57
106
|
}
|
|
58
|
-
export
|
|
59
|
-
|
|
107
|
+
export function correctLunarDate(date, minDate, maxDate) {
|
|
108
|
+
const lunarMinDate = solarToLunar(minDate.getFullYear(), minDate.getMonth() + 1, minDate.getDate());
|
|
109
|
+
const lunarMaxDate = solarToLunar(maxDate.getFullYear(), maxDate.getMonth() + 1, maxDate.getDate());
|
|
110
|
+
const range = [
|
|
111
|
+
{
|
|
112
|
+
value: 0,
|
|
113
|
+
edge: true,
|
|
114
|
+
date: minDate,
|
|
115
|
+
lunarDate: lunarMinDate,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
value: 0,
|
|
119
|
+
edge: true,
|
|
120
|
+
date: maxDate,
|
|
121
|
+
lunarDate: lunarMaxDate,
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
let prevGetter = strategies.y[4];
|
|
125
|
+
letterArray.slice(1).forEach((letter, index) => {
|
|
126
|
+
const prevValue = date[index];
|
|
127
|
+
const currIndex = index + 1;
|
|
128
|
+
const currValue = date[currIndex];
|
|
129
|
+
const strategy = strategies[letter];
|
|
130
|
+
range[0].value = strategy[2];
|
|
131
|
+
range[1].value = strategy[3];
|
|
132
|
+
if (letter === 'd') {
|
|
133
|
+
range[1].value =
|
|
134
|
+
date[1] < 0
|
|
135
|
+
? getLunarLeapMonthDays(date[0])
|
|
136
|
+
: getLunarMonthDays(date[0], date[1]);
|
|
137
|
+
}
|
|
138
|
+
let currGetter = strategy[4];
|
|
139
|
+
range.forEach((point) => {
|
|
140
|
+
if (point.edge) {
|
|
141
|
+
if (letter === 'M') {
|
|
142
|
+
point.edge = point.lunarDate.year === prevValue;
|
|
143
|
+
if (point.edge) {
|
|
144
|
+
point.value = point.lunarDate.month;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (letter === 'd') {
|
|
148
|
+
point.edge = point.lunarDate.month === prevValue;
|
|
149
|
+
if (point.edge) {
|
|
150
|
+
point.value = point.lunarDate.day;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
point.edge = prevGetter(point.date) === prevValue;
|
|
155
|
+
if (point.edge) {
|
|
156
|
+
point.value = currGetter(point.date);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
if (letter === 'M') {
|
|
162
|
+
let min = range[0].value;
|
|
163
|
+
let max = range[1].value;
|
|
164
|
+
let value = currValue;
|
|
165
|
+
if (min < 0) {
|
|
166
|
+
min = Math.abs(min) + 0.5;
|
|
167
|
+
}
|
|
168
|
+
else if (max < 0) {
|
|
169
|
+
max = Math.abs(max) + 0.5;
|
|
170
|
+
}
|
|
171
|
+
if (value < 0) {
|
|
172
|
+
value = Math.abs(value) + 0.5;
|
|
173
|
+
}
|
|
174
|
+
value = minmax(value, min, max);
|
|
175
|
+
date[currIndex] = value % 1 === 0.5 ? ~~value * -1 : value;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
date[currIndex] = minmax(currValue, range[0].value, range[1].value);
|
|
179
|
+
}
|
|
180
|
+
if (letter === 'd') {
|
|
181
|
+
currGetter = (date) => {
|
|
182
|
+
return date === minDate ? lunarMinDate.day : lunarMaxDate.day;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
prevGetter = currGetter;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export function correctDate(calendar, date, minDate, maxDate) {
|
|
189
|
+
if (calendar === 'solar') {
|
|
190
|
+
correctSolarDate(date, minDate, maxDate);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
correctLunarDate(date, minDate, maxDate);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export const getColumnData = (calendar, min, max, length, letter, currentDate, translate, filter, formatter) => {
|
|
197
|
+
const lunarDate = solarToLunar(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate());
|
|
198
|
+
let column = Array(Math.abs(max) - Math.abs(min) + 1)
|
|
60
199
|
.fill(0)
|
|
61
200
|
.map((_, i) => ({
|
|
62
|
-
value: i +
|
|
201
|
+
value: i + Math.abs(min),
|
|
63
202
|
}));
|
|
203
|
+
if (calendar === 'lunar' && letter === 'M') {
|
|
204
|
+
if (min < 0) {
|
|
205
|
+
column[0].value = min;
|
|
206
|
+
}
|
|
207
|
+
else if (max < 0) {
|
|
208
|
+
column.push({
|
|
209
|
+
value: max,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const leapMonth = getLunarLeapMonth(lunarDate.year);
|
|
214
|
+
if (leapMonth > 0 && leapMonth > min && leapMonth < max) {
|
|
215
|
+
column.splice(column.findIndex((item) => item.value === leapMonth) + 1, 0, {
|
|
216
|
+
value: -leapMonth,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
64
221
|
if (filter) {
|
|
65
222
|
column = column.filter((option, i) => filter(letter, option.value, currentDate, i));
|
|
66
223
|
}
|
|
67
224
|
column.forEach((option) => {
|
|
68
225
|
option.zerofill = String(option.value).padStart(length, '0');
|
|
69
|
-
|
|
226
|
+
if (calendar === 'solar') {
|
|
227
|
+
option.label = option.zerofill + translate(letter);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
switch (letter) {
|
|
231
|
+
case 'M':
|
|
232
|
+
option.label = getLunarMonthName(Math.abs(option.value), option.value < 0);
|
|
233
|
+
break;
|
|
234
|
+
case 'd':
|
|
235
|
+
option.label = getLunarDayName(option.value);
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
option.label = option.zerofill + translate(letter);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
70
242
|
});
|
|
71
243
|
if (formatter) {
|
|
72
244
|
column.forEach((option, i) => {
|
|
@@ -8,6 +8,7 @@ declare const __VLS_component: import("vue").DefineComponent<DatetimePickerProps
|
|
|
8
8
|
onChange?: ((date: string | Date) => any) | undefined;
|
|
9
9
|
}>, {
|
|
10
10
|
type: string;
|
|
11
|
+
calendar: "solar" | "lunar";
|
|
11
12
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
13
|
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
13
14
|
export default _default;
|
|
@@ -11,7 +11,14 @@
|
|
|
11
11
|
<script>
|
|
12
12
|
import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from "vue";
|
|
13
13
|
import { computed, ref, watch } from "vue";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
classNames,
|
|
16
|
+
formatDate,
|
|
17
|
+
lunarToSolar,
|
|
18
|
+
solarToLunar,
|
|
19
|
+
stringifyStyle,
|
|
20
|
+
toDate
|
|
21
|
+
} from "../../utils";
|
|
15
22
|
import SarPicker from "../picker/picker.vue";
|
|
16
23
|
import {
|
|
17
24
|
correctDate,
|
|
@@ -39,6 +46,7 @@ export default _defineComponent({
|
|
|
39
46
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
40
47
|
rootClass: { type: String, required: false },
|
|
41
48
|
type: { type: String, required: false },
|
|
49
|
+
calendar: { type: String, required: false },
|
|
42
50
|
min: { type: [Date, String], required: false },
|
|
43
51
|
max: { type: [Date, String], required: false },
|
|
44
52
|
modelValue: { type: [Date, String], required: false },
|
|
@@ -53,14 +61,20 @@ export default _defineComponent({
|
|
|
53
61
|
const emit = __emit;
|
|
54
62
|
const { t } = useTranslate("datetimePicker");
|
|
55
63
|
const createColumnData = (types, currentDate) => {
|
|
56
|
-
minValues = getBoundaryValue(
|
|
57
|
-
|
|
64
|
+
minValues = getBoundaryValue(
|
|
65
|
+
props.calendar,
|
|
66
|
+
false,
|
|
67
|
+
minDate.value,
|
|
68
|
+
currentDate
|
|
69
|
+
);
|
|
70
|
+
maxValues = getBoundaryValue(props.calendar, true, maxDate.value, currentDate);
|
|
58
71
|
const getColumnDataByType = (letter) => {
|
|
59
72
|
const strategy = strategies[letter];
|
|
60
73
|
const index = strategy[0];
|
|
61
74
|
return getColumnData(
|
|
62
|
-
|
|
75
|
+
props.calendar,
|
|
63
76
|
minValues[index],
|
|
77
|
+
maxValues[index],
|
|
64
78
|
strategy[1],
|
|
65
79
|
letter,
|
|
66
80
|
currentDate,
|
|
@@ -74,14 +88,24 @@ export default _defineComponent({
|
|
|
74
88
|
);
|
|
75
89
|
};
|
|
76
90
|
const getChangedLetter = (currentDate) => {
|
|
77
|
-
const min = getBoundaryValue(
|
|
78
|
-
|
|
91
|
+
const min = getBoundaryValue(
|
|
92
|
+
props.calendar,
|
|
93
|
+
false,
|
|
94
|
+
minDate.value,
|
|
95
|
+
currentDate
|
|
96
|
+
);
|
|
97
|
+
const max = getBoundaryValue(props.calendar, true, maxDate.value, currentDate);
|
|
79
98
|
return letterArray.filter(
|
|
80
99
|
(_, i) => min[i] !== minValues[i] || max[i] !== maxValues[i]
|
|
81
100
|
);
|
|
82
101
|
};
|
|
102
|
+
let lunarYearChanged = false;
|
|
83
103
|
const updateColumns = (currentDate) => {
|
|
84
104
|
const changedLetter = getChangedLetter(currentDate);
|
|
105
|
+
if (props.calendar === "lunar" && !changedLetter.includes("M") && innerType.value.includes("M") && lunarYearChanged) {
|
|
106
|
+
changedLetter.push("M");
|
|
107
|
+
lunarYearChanged = false;
|
|
108
|
+
}
|
|
85
109
|
if (changedLetter.length) {
|
|
86
110
|
const changedColumns = createColumnData(changedLetter, currentDate);
|
|
87
111
|
const nextColumns = innerType.value.map((letter) => {
|
|
@@ -96,18 +120,66 @@ export default _defineComponent({
|
|
|
96
120
|
}
|
|
97
121
|
};
|
|
98
122
|
const getDateByPickerValue = (value) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
123
|
+
let currEvery;
|
|
124
|
+
if (props.calendar === "solar") {
|
|
125
|
+
currEvery = letterArray.map((letter) => {
|
|
126
|
+
const stratery = strategies[letter];
|
|
127
|
+
for (let i = 0, l = innerType.value.length; i < l; i++) {
|
|
128
|
+
if (innerType.value[i] === letter) {
|
|
129
|
+
return value[i];
|
|
130
|
+
}
|
|
104
131
|
}
|
|
132
|
+
return stratery[4](innerValue.value);
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
const lunarDate = solarToLunar(
|
|
136
|
+
innerValue.value.getFullYear(),
|
|
137
|
+
innerValue.value.getMonth() + 1,
|
|
138
|
+
innerValue.value.getDate()
|
|
139
|
+
);
|
|
140
|
+
const yearIndex = innerType.value.indexOf("y");
|
|
141
|
+
if (yearIndex !== -1) {
|
|
142
|
+
lunarYearChanged = lunarDate.year !== value[yearIndex];
|
|
105
143
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
144
|
+
currEvery = letterArray.map((letter) => {
|
|
145
|
+
for (let i = 0, l = innerType.value.length; i < l; i++) {
|
|
146
|
+
if (innerType.value[i] === letter) {
|
|
147
|
+
return value[i];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
switch (letter) {
|
|
151
|
+
case "y":
|
|
152
|
+
return lunarDate.year;
|
|
153
|
+
case "M":
|
|
154
|
+
return lunarDate.month;
|
|
155
|
+
case "d":
|
|
156
|
+
return lunarDate.day;
|
|
157
|
+
default:
|
|
158
|
+
return strategies[letter][4](innerValue.value);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
correctDate(
|
|
163
|
+
props.calendar,
|
|
164
|
+
currEvery,
|
|
165
|
+
minDate.value,
|
|
166
|
+
maxDate.value
|
|
167
|
+
);
|
|
168
|
+
let date;
|
|
169
|
+
if (props.calendar === "solar") {
|
|
170
|
+
currEvery[1]--;
|
|
171
|
+
date = new Date(...currEvery);
|
|
172
|
+
} else {
|
|
173
|
+
const solarDate = lunarToSolar(currEvery[0], currEvery[1], currEvery[2]);
|
|
174
|
+
date = new Date(
|
|
175
|
+
solarDate.year,
|
|
176
|
+
solarDate.month - 1,
|
|
177
|
+
solarDate.day,
|
|
178
|
+
currEvery[3],
|
|
179
|
+
currEvery[4],
|
|
180
|
+
currEvery[5]
|
|
181
|
+
);
|
|
182
|
+
}
|
|
111
183
|
return date;
|
|
112
184
|
};
|
|
113
185
|
const normalizeValue = (value) => {
|
|
@@ -153,9 +225,29 @@ export default _defineComponent({
|
|
|
153
225
|
}
|
|
154
226
|
});
|
|
155
227
|
const pickerValue = computed(() => {
|
|
156
|
-
|
|
157
|
-
return
|
|
158
|
-
|
|
228
|
+
if (props.calendar === "solar") {
|
|
229
|
+
return innerType.value.map((letter) => {
|
|
230
|
+
return strategies[letter][4](innerValue.value);
|
|
231
|
+
});
|
|
232
|
+
} else {
|
|
233
|
+
const lunarDate = solarToLunar(
|
|
234
|
+
innerValue.value.getFullYear(),
|
|
235
|
+
innerValue.value.getMonth() + 1,
|
|
236
|
+
innerValue.value.getDate()
|
|
237
|
+
);
|
|
238
|
+
return innerType.value.map((letter) => {
|
|
239
|
+
switch (letter) {
|
|
240
|
+
case "y":
|
|
241
|
+
return lunarDate.year;
|
|
242
|
+
case "M":
|
|
243
|
+
return lunarDate.month;
|
|
244
|
+
case "d":
|
|
245
|
+
return lunarDate.day;
|
|
246
|
+
default:
|
|
247
|
+
return strategies[letter][4](innerValue.value);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
159
251
|
});
|
|
160
252
|
const columnsMap = {};
|
|
161
253
|
let minValues = [];
|
|
@@ -168,7 +260,11 @@ export default _defineComponent({
|
|
|
168
260
|
updateColumns(nextValue);
|
|
169
261
|
emitChange();
|
|
170
262
|
};
|
|
171
|
-
const __returned__ = { props, emit, t, createColumnData, getChangedLetter,
|
|
263
|
+
const __returned__ = { props, emit, t, createColumnData, getChangedLetter, get lunarYearChanged() {
|
|
264
|
+
return lunarYearChanged;
|
|
265
|
+
}, set lunarYearChanged(v) {
|
|
266
|
+
lunarYearChanged = v;
|
|
267
|
+
}, updateColumns, getDateByPickerValue, normalizeValue, innerType, minDate, maxDate, innerValue, get currentEmitValue() {
|
|
172
268
|
return currentEmitValue;
|
|
173
269
|
}, set currentEmitValue(v) {
|
|
174
270
|
currentEmitValue = v;
|
|
@@ -6,6 +6,7 @@ export interface DatetimePickerInputProps extends DatetimePickerPopoutProps, Omi
|
|
|
6
6
|
export declare const defaultDatetimePickerInputProps: () => {
|
|
7
7
|
validateEvent: boolean;
|
|
8
8
|
type: string;
|
|
9
|
+
calendar: "solar";
|
|
9
10
|
};
|
|
10
11
|
export interface DatetimePickerInputSlots extends DatetimePickerPopoutSlots {
|
|
11
12
|
}
|
|
@@ -11,6 +11,7 @@ declare const __VLS_component: import("vue").DefineComponent<DatetimePickerInput
|
|
|
11
11
|
}>, {
|
|
12
12
|
type: string;
|
|
13
13
|
validateEvent: boolean;
|
|
14
|
+
calendar: "solar" | "lunar";
|
|
14
15
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
16
|
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
16
17
|
export default _default;
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
:formatter="formatter"
|
|
25
25
|
:value-format="valueFormat"
|
|
26
26
|
:validate-event="validateEvent"
|
|
27
|
+
:calendar="calendar"
|
|
27
28
|
@change="onChange"
|
|
28
29
|
/>
|
|
29
30
|
</sar-popout-input>
|
|
@@ -62,6 +63,7 @@ export default _defineComponent({
|
|
|
62
63
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
63
64
|
rootClass: { type: String, required: false },
|
|
64
65
|
type: { type: String, required: false },
|
|
66
|
+
calendar: { type: String, required: false },
|
|
65
67
|
min: { type: [Date, String], required: false },
|
|
66
68
|
max: { type: [Date, String], required: false },
|
|
67
69
|
modelValue: { type: [Date, String], required: false },
|
|
@@ -10,6 +10,7 @@ export interface DatetimePickerPopoutProps extends DatetimePickerProps {
|
|
|
10
10
|
export declare const defaultDatetimePickerPopoutProps: () => {
|
|
11
11
|
validateEvent: boolean;
|
|
12
12
|
type: string;
|
|
13
|
+
calendar: "solar";
|
|
13
14
|
};
|
|
14
15
|
export interface DatetimePickerPopoutSlots extends DatetimePickerSlots {
|
|
15
16
|
}
|
|
@@ -11,6 +11,7 @@ declare const __VLS_component: import("vue").DefineComponent<DatetimePickerPopou
|
|
|
11
11
|
}>, {
|
|
12
12
|
type: string;
|
|
13
13
|
validateEvent: boolean;
|
|
14
|
+
calendar: "solar" | "lunar";
|
|
14
15
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
16
|
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
16
17
|
export default _default;
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
:filter="filter"
|
|
19
19
|
:formatter="formatter"
|
|
20
20
|
:value-format="valueFormat"
|
|
21
|
+
:calendar="calendar"
|
|
21
22
|
@change="onChange"
|
|
22
23
|
/>
|
|
23
24
|
</template>
|
|
@@ -60,6 +61,7 @@ export default _defineComponent({
|
|
|
60
61
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
61
62
|
rootClass: { type: String, required: false },
|
|
62
63
|
type: { type: String, required: false },
|
|
64
|
+
calendar: { type: String, required: false },
|
|
63
65
|
min: { type: [Date, String], required: false },
|
|
64
66
|
max: { type: [Date, String], required: false },
|
|
65
67
|
modelValue: { type: [Date, String], required: false },
|
|
@@ -69,6 +69,7 @@ export default _defineComponent({
|
|
|
69
69
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
70
70
|
rootClass: { type: String, required: false },
|
|
71
71
|
type: { type: String, required: false },
|
|
72
|
+
calendar: { type: String, required: false },
|
|
72
73
|
min: { type: [Date, String], required: false },
|
|
73
74
|
max: { type: [Date, String], required: false },
|
|
74
75
|
filter: { type: Function, required: false },
|
|
@@ -66,6 +66,7 @@ export default _defineComponent({
|
|
|
66
66
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
67
67
|
rootClass: { type: String, required: false },
|
|
68
68
|
type: { type: String, required: false },
|
|
69
|
+
calendar: { type: String, required: false },
|
|
69
70
|
min: { type: [Date, String], required: false },
|
|
70
71
|
max: { type: [Date, String], required: false },
|
|
71
72
|
filter: { type: Function, required: false },
|
|
@@ -63,6 +63,7 @@ export default _defineComponent({
|
|
|
63
63
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
64
64
|
rootClass: { type: String, required: false },
|
|
65
65
|
type: { type: String, required: false },
|
|
66
|
+
calendar: { type: String, required: false },
|
|
66
67
|
min: { type: [Date, String], required: false },
|
|
67
68
|
max: { type: [Date, String], required: false },
|
|
68
69
|
filter: { type: Function, required: false },
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type StyleValue, type Ref } from 'vue';
|
|
2
|
+
import { type TransitionHookEmits } from '../popup/common';
|
|
2
3
|
export interface DropdownProps {
|
|
3
4
|
rootStyle?: StyleValue;
|
|
4
5
|
rootClass?: string;
|
|
@@ -40,7 +41,7 @@ export declare const defaultDropdownItemProps: {
|
|
|
40
41
|
export interface DropdownItemSlots {
|
|
41
42
|
default?(props: Record<string, never>): any;
|
|
42
43
|
}
|
|
43
|
-
export interface DropdownItemEmits {
|
|
44
|
+
export interface DropdownItemEmits extends TransitionHookEmits {
|
|
44
45
|
(e: 'update:model-value', value: any): void;
|
|
45
46
|
(e: 'change', value: any): void;
|
|
46
47
|
(e: 'update:visible', visible: boolean): void;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type DropdownItemProps, type DropdownItemSlots, type DropdownOption } from '../dropdown/common';
|
|
2
2
|
declare function __VLS_template(): Readonly<DropdownItemSlots> & DropdownItemSlots;
|
|
3
|
-
declare const __VLS_component: import("vue").DefineComponent<DropdownItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
declare const __VLS_component: import("vue").DefineComponent<DropdownItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
4
|
+
[x: string]: any;
|
|
5
|
+
} & {
|
|
6
|
+
[x: string]: any;
|
|
7
7
|
}, string, import("vue").PublicProps, Readonly<DropdownItemProps> & Readonly<{
|
|
8
|
-
|
|
9
|
-
onChange?: ((value: any) => any) | undefined;
|
|
10
|
-
"onUpdate:visible"?: ((visible: boolean) => any) | undefined;
|
|
8
|
+
[x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
|
|
11
9
|
}>, {
|
|
12
10
|
options: DropdownOption[];
|
|
13
11
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -128,7 +128,7 @@ export default _defineComponent({
|
|
|
128
128
|
separator: { type: String, required: false },
|
|
129
129
|
placeholder: { type: String, required: false }
|
|
130
130
|
}, defaultDropdownItemProps),
|
|
131
|
-
emits: ["update:model-value", "change", "update:visible"],
|
|
131
|
+
emits: ["update:model-value", "change", "update:visible", "before-enter", "enter", "after-enter", "enter-cancelled", "before-leave", "leave", "after-leave", "leave-cancelled", "visible-hook"],
|
|
132
132
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
133
133
|
__expose();
|
|
134
134
|
const props = __props;
|
|
@@ -254,6 +254,8 @@ export default _defineComponent({
|
|
|
254
254
|
if (name === "after-leave") {
|
|
255
255
|
onAfterLeave();
|
|
256
256
|
}
|
|
257
|
+
emit("visible-hook", name);
|
|
258
|
+
emit(name);
|
|
257
259
|
}
|
|
258
260
|
})
|
|
259
261
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<view :class="emptyClass" :style="emptyStyle">
|
|
3
3
|
<view :class="bem.e('icon')" :style="iconStyle">
|
|
4
4
|
<slot name="icon">
|
|
5
|
-
<sar-icon :family="iconFamily
|
|
5
|
+
<sar-icon :family="iconFamily" :name="icon" />
|
|
6
6
|
</slot>
|
|
7
7
|
</view>
|
|
8
8
|
<slot name="description">
|
package/components/fab/fab.vue
CHANGED
package/components/icon/icon.vue
CHANGED
|
@@ -33,12 +33,17 @@ export default _defineComponent({
|
|
|
33
33
|
return isFileUrl(props.name);
|
|
34
34
|
});
|
|
35
35
|
const iconClass = computed(() => {
|
|
36
|
+
if (isImg.value) {
|
|
37
|
+
return classNames(bem.b(), props.rootClass);
|
|
38
|
+
}
|
|
39
|
+
if (props.name.includes(":")) {
|
|
40
|
+
const [family, name] = props.name.split(":");
|
|
41
|
+
return classNames(bem.b(), family, `${family}-${name}`, props.rootClass);
|
|
42
|
+
}
|
|
36
43
|
return classNames(
|
|
37
44
|
bem.b(),
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
[`${props.family}-${props.name}`]: !isImg.value
|
|
41
|
-
},
|
|
45
|
+
props.family,
|
|
46
|
+
`${props.family}-${props.name}`,
|
|
42
47
|
props.rootClass
|
|
43
48
|
);
|
|
44
49
|
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
v-if="icon || (withIcon && direction === 'vertical')"
|
|
5
5
|
:class="bem.e('icon')"
|
|
6
6
|
>
|
|
7
|
-
<sar-icon v-if="icon" :name="icon" :family="iconFamily
|
|
7
|
+
<sar-icon v-if="icon" :name="icon" :family="iconFamily" />
|
|
8
8
|
</view>
|
|
9
9
|
<view v-if="text" :class="bem.e('text')">
|
|
10
10
|
{{ text }}
|
package/components/rate/rate.vue
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<template v-if="voidText">
|
|
32
32
|
{{ voidText }}
|
|
33
33
|
</template>
|
|
34
|
-
<sar-icon v-else :name="voidIcon" :family="iconFamily
|
|
34
|
+
<sar-icon v-else :name="voidIcon" :family="iconFamily" />
|
|
35
35
|
</view>
|
|
36
36
|
<view
|
|
37
37
|
:class="bem.e('star')"
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
<template v-if="text">
|
|
46
46
|
{{ text }}
|
|
47
47
|
</template>
|
|
48
|
-
<sar-icon v-else :name="icon" :family="iconFamily
|
|
48
|
+
<sar-icon v-else :name="icon" :family="iconFamily" />
|
|
49
49
|
</view>
|
|
50
50
|
</view>
|
|
51
51
|
</view>
|
package/components/step/step.vue
CHANGED
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
<slot>
|
|
4
4
|
<view :class="bem.e('icon')">
|
|
5
5
|
<slot name="icon" :active="isCurrent">
|
|
6
|
-
<sar-icon
|
|
7
|
-
:name="icon"
|
|
8
|
-
:family="iconFamily || 'sari'"
|
|
9
|
-
:size="iconSize"
|
|
10
|
-
/>
|
|
6
|
+
<sar-icon :name="icon" :family="iconFamily" :size="iconSize" />
|
|
11
7
|
</slot>
|
|
12
8
|
<sar-badge v-if="badge || dot" :value="badge" :dot="dot" fixed />
|
|
13
9
|
</view>
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
<view :class="bem.e('icon-wrapper')">
|
|
6
6
|
<view v-if="icon || $slots.icon" :class="bem.e('icon')">
|
|
7
7
|
<slot name="icon">
|
|
8
|
-
<sar-icon
|
|
9
|
-
:name="icon"
|
|
10
|
-
:family="iconFamily || 'sari'"
|
|
11
|
-
:color="iconColor"
|
|
12
|
-
/>
|
|
8
|
+
<sar-icon :name="icon" :family="iconFamily" :color="iconColor" />
|
|
13
9
|
</slot>
|
|
14
10
|
</view>
|
|
15
11
|
<view v-else :class="bem.e('dot')"></view>
|
package/package.json
CHANGED
package/utils/date.d.ts
CHANGED
|
@@ -1,16 +1,46 @@
|
|
|
1
1
|
export declare function isLeapYear(year: number): boolean;
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function
|
|
2
|
+
export declare function getMonthDays(year: number, month: number): number;
|
|
3
|
+
export declare function getDaysInYear(date: Date): number;
|
|
4
|
+
export declare function getWeekOfMonthStart(year: number, month: number): number;
|
|
4
5
|
export declare function getDaysInDate(date: Date): number;
|
|
5
6
|
export declare function toDateNumber(date: Date): number;
|
|
6
7
|
export declare function toDateString(date: Date): string;
|
|
7
8
|
export declare function toMonthNumber(date: Date): number;
|
|
8
9
|
export declare function getPadStartDays(year: number, month: number, amount: number): Date[];
|
|
9
10
|
export declare function getPadEndDays(year: number, month: number, amount: number): Date[];
|
|
10
|
-
export declare function
|
|
11
|
+
export declare function getOffsetDaysFromMonthStart(weekOnMonthStart: number, weekStartsOn: number): number;
|
|
11
12
|
export declare function formatDate(date: Date, format?: string): string;
|
|
12
13
|
export declare function parseDate(value: string, format?: string): Date;
|
|
13
14
|
export declare function toDate(date: Date | string, valueFormat?: string): Date;
|
|
14
15
|
export declare function minmaxDate(date: Date, minDate: Date, maxDate: Date): Date;
|
|
15
16
|
export declare function getPrevMonthDate(date: Date): Date;
|
|
16
17
|
export declare function getNextMonthDate(date: Date): Date;
|
|
18
|
+
/****************************************************************
|
|
19
|
+
* 农历
|
|
20
|
+
****************************************************************/
|
|
21
|
+
export declare const lunarInfo: number[];
|
|
22
|
+
export declare const springFestivals: number[][];
|
|
23
|
+
export declare const baseLunarYear = 1900;
|
|
24
|
+
export declare function getLunarLeapMonth(year: number): number;
|
|
25
|
+
export declare function getLunarLeapMonthDays(year: number): 0 | 30 | 29;
|
|
26
|
+
export declare function getLunarYearDays(year: number): number;
|
|
27
|
+
export declare function getLunarMonthDays(year: number, month: number): 30 | 29;
|
|
28
|
+
export declare function solarToLunar(year: number, _month: number, date: number): {
|
|
29
|
+
year: number;
|
|
30
|
+
month: number;
|
|
31
|
+
day: number;
|
|
32
|
+
};
|
|
33
|
+
export declare function lunarToSolar(lunarYear: number, lunarMonth: number, lunarDay: number): {
|
|
34
|
+
year: number;
|
|
35
|
+
month: number;
|
|
36
|
+
day: number;
|
|
37
|
+
};
|
|
38
|
+
export declare const lunarYearNames: string[];
|
|
39
|
+
export declare function getLunarYearName(year: number): string;
|
|
40
|
+
export declare const lunarMonthNames: string[];
|
|
41
|
+
export declare function getLunarMonthName(month: number, isLeapMonth?: boolean): string;
|
|
42
|
+
export declare const lunarDayNames: string[];
|
|
43
|
+
export declare function getLunarDayName(day: number): string;
|
|
44
|
+
export declare const heavenlyStems: string[];
|
|
45
|
+
export declare const earthlyBranches: string[];
|
|
46
|
+
export declare function getLunarHourName(hour: number): string;
|
package/utils/date.js
CHANGED
|
@@ -4,19 +4,30 @@ import { minmax } from './utils';
|
|
|
4
4
|
export function isLeapYear(year) {
|
|
5
5
|
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
8
|
+
// 获取某月的天数
|
|
9
|
+
export function getMonthDays(year, month) {
|
|
10
10
|
if (month === 2) {
|
|
11
11
|
return isLeapYear(year) ? 29 : 28;
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
return [
|
|
14
|
+
return monthDays[month - 1];
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
//
|
|
18
|
-
export function
|
|
19
|
-
|
|
17
|
+
// 获取当前日期是一年中的第几天
|
|
18
|
+
export function getDaysInYear(date) {
|
|
19
|
+
const year = date.getFullYear();
|
|
20
|
+
const month = date.getMonth();
|
|
21
|
+
const d = date.getDate();
|
|
22
|
+
let days = 0;
|
|
23
|
+
for (let m = 0; m < month; m++) {
|
|
24
|
+
days += getMonthDays(year, m + 1);
|
|
25
|
+
}
|
|
26
|
+
return days + d;
|
|
27
|
+
}
|
|
28
|
+
// 获取某月一号对应是星期几
|
|
29
|
+
export function getWeekOfMonthStart(year, month) {
|
|
30
|
+
return new Date(year, month - 1, 1).getDay();
|
|
20
31
|
}
|
|
21
32
|
// 获取 Date 中的总天数
|
|
22
33
|
export function getDaysInDate(date) {
|
|
@@ -38,7 +49,7 @@ export function toMonthNumber(date) {
|
|
|
38
49
|
export function getPadStartDays(year, month, amount) {
|
|
39
50
|
const dates = [];
|
|
40
51
|
for (let i = amount - 1; i >= 0; i--) {
|
|
41
|
-
dates.push(new Date(year, month, -i));
|
|
52
|
+
dates.push(new Date(year, month - 1, -i));
|
|
42
53
|
}
|
|
43
54
|
return dates;
|
|
44
55
|
}
|
|
@@ -46,13 +57,13 @@ export function getPadStartDays(year, month, amount) {
|
|
|
46
57
|
export function getPadEndDays(year, month, amount) {
|
|
47
58
|
const dates = [];
|
|
48
59
|
for (let i = 1; i <= amount; i++) {
|
|
49
|
-
dates.push(new Date(year, month + 1, i));
|
|
60
|
+
dates.push(new Date(year, month + 1 - 1, i));
|
|
50
61
|
}
|
|
51
62
|
return dates;
|
|
52
63
|
}
|
|
53
64
|
// 获取一号偏移的天数
|
|
54
|
-
export function
|
|
55
|
-
return (
|
|
65
|
+
export function getOffsetDaysFromMonthStart(weekOnMonthStart, weekStartsOn) {
|
|
66
|
+
return (weekOnMonthStart - weekStartsOn + 7) % 7;
|
|
56
67
|
}
|
|
57
68
|
const dateTokensReg = /(YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s|SSS)/g;
|
|
58
69
|
const dateGetters = {
|
|
@@ -147,3 +158,190 @@ export function getPrevMonthDate(date) {
|
|
|
147
158
|
export function getNextMonthDate(date) {
|
|
148
159
|
return new Date(date.getFullYear(), date.getMonth() + 1, 1);
|
|
149
160
|
}
|
|
161
|
+
/****************************************************************
|
|
162
|
+
* 农历
|
|
163
|
+
****************************************************************/
|
|
164
|
+
// prettier-ignore
|
|
165
|
+
export const lunarInfo = [
|
|
166
|
+
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
|
|
167
|
+
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
|
|
168
|
+
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
|
|
169
|
+
0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
|
|
170
|
+
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
|
|
171
|
+
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
|
|
172
|
+
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
|
|
173
|
+
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
|
|
174
|
+
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
|
|
175
|
+
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
|
|
176
|
+
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
|
|
177
|
+
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
|
|
178
|
+
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
|
|
179
|
+
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
|
|
180
|
+
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
|
|
181
|
+
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
|
|
182
|
+
0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
|
|
183
|
+
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
|
|
184
|
+
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
|
|
185
|
+
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
|
|
186
|
+
0x0d520, // 2100
|
|
187
|
+
];
|
|
188
|
+
// 1900-2100春节对应的公历日期
|
|
189
|
+
// prettier-ignore
|
|
190
|
+
export const springFestivals = [
|
|
191
|
+
[1, 31], [2, 19], [2, 8], [1, 29], [2, 16], [2, 4], [1, 25], [2, 13], [2, 2], [1, 22], // 1900-1909
|
|
192
|
+
[2, 10], [1, 30], [2, 18], [2, 6], [1, 26], [2, 14], [2, 3], [1, 23], [2, 11], [2, 1], // 1910-1919
|
|
193
|
+
[2, 20], [2, 8], [1, 28], [2, 16], [2, 5], [1, 24], [2, 13], [2, 2], [1, 23], [2, 10], // 1920-1929
|
|
194
|
+
[1, 30], [2, 17], [2, 6], [1, 26], [2, 14], [2, 4], [1, 24], [2, 11], [1, 31], [2, 19], // 1930-1939
|
|
195
|
+
[2, 8], [1, 27], [2, 15], [2, 5], [1, 25], [2, 13], [2, 2], [1, 22], [2, 10], [1, 29], // 1940-1949
|
|
196
|
+
[2, 17], [2, 6], [1, 27], [2, 14], [2, 3], [1, 24], [2, 12], [1, 31], [2, 18], [2, 8], // 1950-1959
|
|
197
|
+
[1, 28], [2, 15], [2, 5], [1, 25], [2, 13], [2, 2], [1, 21], [2, 9], [1, 30], [2, 17], // 1960-1969
|
|
198
|
+
[2, 6], [1, 27], [2, 15], [2, 3], [1, 23], [2, 11], [1, 31], [2, 18], [2, 7], [1, 28], // 1970-1979
|
|
199
|
+
[2, 16], [2, 5], [1, 25], [2, 13], [2, 2], [2, 20], [2, 9], [1, 29], [2, 17], [2, 6], // 1980-1989
|
|
200
|
+
[1, 27], [2, 15], [2, 4], [1, 23], [2, 10], [1, 31], [2, 19], [2, 7], [1, 28], [2, 16], // 1990-1999
|
|
201
|
+
[2, 5], [1, 24], [2, 12], [2, 1], [1, 22], [2, 9], [1, 29], [2, 18], [2, 7], [1, 26], // 2000-2009
|
|
202
|
+
[2, 14], [2, 3], [1, 23], [2, 10], [1, 31], [2, 19], [2, 8], [1, 28], [2, 16], [2, 5], // 2010-2019
|
|
203
|
+
[1, 25], [2, 12], [2, 1], [1, 22], [2, 10], [1, 29], [2, 17], [2, 6], [1, 26], [2, 13], // 2020-2029
|
|
204
|
+
[2, 3], [1, 23], [2, 11], [1, 31], [2, 19], [2, 8], [1, 28], [2, 15], [2, 4], [1, 24], // 2030-2039
|
|
205
|
+
[2, 12], [2, 1], [1, 22], [2, 10], [1, 30], [2, 17], [2, 6], [1, 26], [2, 14], [2, 2], // 2040-2049
|
|
206
|
+
[1, 23], [2, 11], [2, 1], [2, 19], [2, 8], [1, 28], [2, 15], [2, 4], [1, 24], [2, 12], // 2050-2059
|
|
207
|
+
[2, 2], [1, 21], [2, 9], [1, 29], [2, 17], [2, 5], [1, 26], [2, 14], [2, 3], [1, 23], // 2060-2069
|
|
208
|
+
[2, 11], [1, 31], [2, 19], [2, 7], [1, 27], [2, 15], [2, 5], [1, 24], [2, 12], [2, 2], // 2070-2079
|
|
209
|
+
[1, 22], [2, 9], [1, 29], [2, 17], [2, 6], [1, 26], [2, 14], [2, 3], [1, 24], [2, 10], // 2080-2089
|
|
210
|
+
[1, 30], [2, 18], [2, 7], [1, 27], [2, 15], [2, 5], [1, 25], [2, 12], [2, 1], [1, 21], // 2090-2099
|
|
211
|
+
[2, 9], // 2100
|
|
212
|
+
];
|
|
213
|
+
export const baseLunarYear = 1900;
|
|
214
|
+
// 获取农历某年闰月的月份(0表示无闰月)
|
|
215
|
+
export function getLunarLeapMonth(year) {
|
|
216
|
+
return lunarInfo[year - baseLunarYear] & 0xf;
|
|
217
|
+
}
|
|
218
|
+
// 获取农历某年闰月的天数
|
|
219
|
+
export function getLunarLeapMonthDays(year) {
|
|
220
|
+
if (getLunarLeapMonth(year)) {
|
|
221
|
+
return lunarInfo[year - baseLunarYear] & 0x10000 ? 30 : 29;
|
|
222
|
+
}
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
// 获取农历某年的总天数
|
|
226
|
+
export function getLunarYearDays(year) {
|
|
227
|
+
let sum = 348; // 29天*12个月
|
|
228
|
+
const info = lunarInfo[year - baseLunarYear];
|
|
229
|
+
// 加上大月的天数
|
|
230
|
+
for (let i = 0x8000; i > 0x8; i >>= 1) {
|
|
231
|
+
sum += info & i ? 1 : 0;
|
|
232
|
+
}
|
|
233
|
+
// 加上闰月的天数
|
|
234
|
+
return sum + getLunarLeapMonthDays(year);
|
|
235
|
+
}
|
|
236
|
+
// 获取农历某年某月的天数
|
|
237
|
+
export function getLunarMonthDays(year, month) {
|
|
238
|
+
return lunarInfo[year - baseLunarYear] & (0x10000 >> month) ? 30 : 29;
|
|
239
|
+
}
|
|
240
|
+
// 公历转农历
|
|
241
|
+
export function solarToLunar(year, _month, date) {
|
|
242
|
+
// 计算输入日期与基准日期的天数差
|
|
243
|
+
const offsetDays = Math.floor((Date.UTC(year, _month - 1, date) - Date.UTC(baseLunarYear, 0, 31)) /
|
|
244
|
+
(24 * 60 * 60 * 1000));
|
|
245
|
+
// 农历年、月、日初始化
|
|
246
|
+
let lunarYear = baseLunarYear;
|
|
247
|
+
let lunarMonth = 1;
|
|
248
|
+
let lunarDay = 1;
|
|
249
|
+
let isLeapMonth = false;
|
|
250
|
+
let daysRemaining = offsetDays;
|
|
251
|
+
// 计算农历年
|
|
252
|
+
while (true) {
|
|
253
|
+
const yearDays = getLunarYearDays(lunarYear);
|
|
254
|
+
if (daysRemaining < yearDays) {
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
daysRemaining -= yearDays;
|
|
258
|
+
lunarYear++;
|
|
259
|
+
}
|
|
260
|
+
// 计算农历月和日
|
|
261
|
+
const leapMonth = getLunarLeapMonth(lunarYear);
|
|
262
|
+
let monthDays = 0;
|
|
263
|
+
let month = 1;
|
|
264
|
+
for (; month <= 12; month++) {
|
|
265
|
+
// 处理闰月
|
|
266
|
+
if (leapMonth > 0 && month === leapMonth + 1) {
|
|
267
|
+
monthDays = getLunarLeapMonthDays(lunarYear);
|
|
268
|
+
if (daysRemaining < monthDays) {
|
|
269
|
+
isLeapMonth = true;
|
|
270
|
+
month--;
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
daysRemaining -= monthDays;
|
|
274
|
+
}
|
|
275
|
+
monthDays = getLunarMonthDays(lunarYear, month);
|
|
276
|
+
if (daysRemaining < monthDays) {
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
daysRemaining -= monthDays;
|
|
280
|
+
}
|
|
281
|
+
lunarMonth = month;
|
|
282
|
+
lunarDay = daysRemaining + 1;
|
|
283
|
+
return {
|
|
284
|
+
year: lunarYear,
|
|
285
|
+
month: lunarMonth * (isLeapMonth ? -1 : 1),
|
|
286
|
+
day: lunarDay,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// 农历转公历(闰月需传递负数)
|
|
290
|
+
export function lunarToSolar(lunarYear, lunarMonth, lunarDay) {
|
|
291
|
+
const springFestival = springFestivals[lunarYear - baseLunarYear];
|
|
292
|
+
const solarDate = new Date(lunarYear, springFestival[0] - 1, springFestival[1]);
|
|
293
|
+
const info = lunarInfo[lunarYear - baseLunarYear];
|
|
294
|
+
const leapMonth = info & 0xf;
|
|
295
|
+
let totalDays = 0;
|
|
296
|
+
const absMonth = Math.abs(lunarMonth);
|
|
297
|
+
for (let m = 1; m < absMonth; m++) {
|
|
298
|
+
if (m === leapMonth) {
|
|
299
|
+
totalDays += getLunarLeapMonthDays(lunarYear);
|
|
300
|
+
}
|
|
301
|
+
totalDays += getLunarMonthDays(lunarYear, m);
|
|
302
|
+
}
|
|
303
|
+
if (lunarMonth < 0) {
|
|
304
|
+
totalDays += getLunarMonthDays(lunarYear, absMonth);
|
|
305
|
+
}
|
|
306
|
+
totalDays += lunarDay - 1;
|
|
307
|
+
solarDate.setDate(solarDate.getDate() + totalDays);
|
|
308
|
+
return {
|
|
309
|
+
year: solarDate.getFullYear(),
|
|
310
|
+
month: solarDate.getMonth() + 1,
|
|
311
|
+
day: solarDate.getDate(),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
// 农历年份的名称
|
|
315
|
+
// prettier-ignore
|
|
316
|
+
export const lunarYearNames = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
|
|
317
|
+
export function getLunarYearName(year) {
|
|
318
|
+
return (String(year)
|
|
319
|
+
.split('')
|
|
320
|
+
.map((item) => lunarYearNames[+item])
|
|
321
|
+
.join('') + '年');
|
|
322
|
+
}
|
|
323
|
+
// 农历月份的名称
|
|
324
|
+
// prettier-ignore
|
|
325
|
+
export const lunarMonthNames = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'];
|
|
326
|
+
// 获取农历月份名称
|
|
327
|
+
export function getLunarMonthName(month, isLeapMonth) {
|
|
328
|
+
return (isLeapMonth ? '闰' : '') + lunarMonthNames[month - 1] + '月';
|
|
329
|
+
}
|
|
330
|
+
// 农历日期的名称
|
|
331
|
+
// prettier-ignore
|
|
332
|
+
export const lunarDayNames = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'];
|
|
333
|
+
// 获取农历日期名称
|
|
334
|
+
export function getLunarDayName(day) {
|
|
335
|
+
return lunarDayNames[day - 1];
|
|
336
|
+
}
|
|
337
|
+
// 十天干
|
|
338
|
+
// prettier-ignore
|
|
339
|
+
export const heavenlyStems = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
340
|
+
// 十二地支
|
|
341
|
+
// prettier-ignore
|
|
342
|
+
export const earthlyBranches = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
|
|
343
|
+
// 获取农历时辰名称
|
|
344
|
+
export function getLunarHourName(hour) {
|
|
345
|
+
const index = Math.floor(((hour === 23 ? 0 : hour) + 1) / 2) % 12;
|
|
346
|
+
return earthlyBranches[index] + (hour % 2 === 1 ? '初' : '正');
|
|
347
|
+
}
|