@momo-kits/calendar 0.0.34-beta → 0.0.34
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.js +4 -1
- package/package.json +7 -12
- package/publish.sh +2 -2
- package/src/Calendar.js +394 -1
- package/src/CalendarPro.js +363 -1
- package/src/Day/index.js +210 -1
- package/src/Day/style.js +129 -1
- package/src/HeaderControl.js +79 -1
- package/src/LunarDateConverter.js +191 -1
- package/src/LunarService.js +185 -1
- package/src/Month/index.js +80 -1
- package/src/MonthList.js +253 -1
- package/src/TabHeader.js +79 -1
- package/src/Util.js +225 -1
- package/src/calendarPicker/Day.js +154 -0
- package/src/calendarPicker/Days.js +203 -0
- package/src/calendarPicker/HeaderControls.js +158 -0
- package/src/calendarPicker/WeekDaysLabels.js +22 -0
- package/src/calendarPicker/index.js +125 -0
- package/src/calendarPicker/styles.js +184 -0
- package/src/calendarPicker/util.js +50 -0
- package/src/holidayData.js +127 -1
- package/babel.config.js +0 -1
package/src/Day/style.js
CHANGED
|
@@ -1 +1,129 @@
|
|
|
1
|
-
|
|
1
|
+
import { Dimensions } from 'react-native';
|
|
2
|
+
import { Colors } from '@momo-kits/core';
|
|
3
|
+
|
|
4
|
+
const dayWidth = (Dimensions.get('window').width - 38) / 7;
|
|
5
|
+
const SCREEN_WIDTH = Dimensions.get('window').width;
|
|
6
|
+
const SCREEN_DPI_WIDTH = (SCREEN_WIDTH * Dimensions.get('window').scale);
|
|
7
|
+
const IPHONE_4_5_WIDTH = 640;
|
|
8
|
+
const dayTextSize = SCREEN_DPI_WIDTH === IPHONE_4_5_WIDTH ? 13 : 15;
|
|
9
|
+
const lunarTextSize = SCREEN_DPI_WIDTH === IPHONE_4_5_WIDTH ? 8 : 10;
|
|
10
|
+
const priceTextSize = SCREEN_DPI_WIDTH === IPHONE_4_5_WIDTH ? 8 : 10;
|
|
11
|
+
const lineHeightDayText = 1.3 * dayTextSize;
|
|
12
|
+
const lineHeightLunarText = 1.3 * lunarTextSize;
|
|
13
|
+
const lineHeightPriceText = 1.3 * priceTextSize;
|
|
14
|
+
const containerDayHeight = lineHeightDayText + lineHeightLunarText + lineHeightPriceText + 10;
|
|
15
|
+
const heightDefault = lineHeightDayText + lineHeightLunarText;
|
|
16
|
+
export default {
|
|
17
|
+
dayContainer: {
|
|
18
|
+
width: dayWidth,
|
|
19
|
+
borderRadius: 4,
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
height: containerDayHeight,
|
|
22
|
+
},
|
|
23
|
+
day: {
|
|
24
|
+
width: dayWidth,
|
|
25
|
+
paddingVertical: 5,
|
|
26
|
+
overflow: 'hidden',
|
|
27
|
+
justifyContent: 'center',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
borderRadius: 4,
|
|
30
|
+
height: heightDefault + 5
|
|
31
|
+
},
|
|
32
|
+
dayText: {
|
|
33
|
+
fontSize: dayTextSize,
|
|
34
|
+
textAlign: 'center',
|
|
35
|
+
fontWeight: 'bold',
|
|
36
|
+
color: '#222222'
|
|
37
|
+
},
|
|
38
|
+
lunarDayText: {
|
|
39
|
+
width: dayWidth,
|
|
40
|
+
textAlign: 'right',
|
|
41
|
+
fontSize: SCREEN_DPI_WIDTH === IPHONE_4_5_WIDTH ? 8 : 10,
|
|
42
|
+
paddingRight: 5,
|
|
43
|
+
color: '#222222'
|
|
44
|
+
},
|
|
45
|
+
todayText: {
|
|
46
|
+
color: 'blue'
|
|
47
|
+
},
|
|
48
|
+
weekendDay: {
|
|
49
|
+
color: '#e82956'
|
|
50
|
+
},
|
|
51
|
+
dayTextDisabled: {
|
|
52
|
+
opacity: 0.2
|
|
53
|
+
},
|
|
54
|
+
focused: {
|
|
55
|
+
backgroundColor: Colors.pink_05_b
|
|
56
|
+
},
|
|
57
|
+
focusedText: {
|
|
58
|
+
color: 'white'
|
|
59
|
+
},
|
|
60
|
+
dayStartContainer: {
|
|
61
|
+
borderTopLeftRadius: 4,
|
|
62
|
+
borderBottomLeftRadius: 4,
|
|
63
|
+
backgroundColor: Colors.pink_09,
|
|
64
|
+
// height: heightDefault
|
|
65
|
+
},
|
|
66
|
+
dayEndContainer: {
|
|
67
|
+
borderTopRightRadius: 4,
|
|
68
|
+
borderBottomRightRadius: 4,
|
|
69
|
+
backgroundColor: Colors.pink_09,
|
|
70
|
+
// height: heightDefault
|
|
71
|
+
},
|
|
72
|
+
mid: {
|
|
73
|
+
backgroundColor: Colors.pink_09,
|
|
74
|
+
// height: heightDefault
|
|
75
|
+
},
|
|
76
|
+
departLabel: {
|
|
77
|
+
position: 'absolute',
|
|
78
|
+
backgroundColor: 'yellow',
|
|
79
|
+
width: 20,
|
|
80
|
+
height: 20,
|
|
81
|
+
borderRadius: 10,
|
|
82
|
+
justifyContent: 'center',
|
|
83
|
+
alignItems: 'center'
|
|
84
|
+
},
|
|
85
|
+
returnLabel: {
|
|
86
|
+
position: 'absolute',
|
|
87
|
+
backgroundColor: 'yellow',
|
|
88
|
+
width: 20,
|
|
89
|
+
height: 20,
|
|
90
|
+
borderRadius: 10,
|
|
91
|
+
justifyContent: 'center',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
top: 0,
|
|
94
|
+
right: 0
|
|
95
|
+
},
|
|
96
|
+
containerDayHeight,
|
|
97
|
+
txtBack: {
|
|
98
|
+
position: 'absolute',
|
|
99
|
+
backgroundColor: '#ffbb1e',
|
|
100
|
+
borderRadius: 100,
|
|
101
|
+
top: -2,
|
|
102
|
+
right: -2,
|
|
103
|
+
zIndex: 999,
|
|
104
|
+
padding: 2,
|
|
105
|
+
width: 15,
|
|
106
|
+
height: 15,
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
alignItems: 'center'
|
|
109
|
+
},
|
|
110
|
+
txtGo: {
|
|
111
|
+
position: 'absolute',
|
|
112
|
+
backgroundColor: '#ffbb1e',
|
|
113
|
+
top: -2,
|
|
114
|
+
left: -2,
|
|
115
|
+
borderRadius: 100,
|
|
116
|
+
padding: 2,
|
|
117
|
+
zIndex: 999,
|
|
118
|
+
width: 15,
|
|
119
|
+
height: 15,
|
|
120
|
+
justifyContent: 'center',
|
|
121
|
+
alignItems: 'center'
|
|
122
|
+
},
|
|
123
|
+
price: {
|
|
124
|
+
fontSize: priceTextSize,
|
|
125
|
+
lineHeight: lineHeightPriceText,
|
|
126
|
+
color: '#8d919d'
|
|
127
|
+
},
|
|
128
|
+
lineHeightPriceText
|
|
129
|
+
};
|
package/src/HeaderControl.js
CHANGED
|
@@ -1 +1,79 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { useState, forwardRef, useImperativeHandle } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View, TouchableOpacity, StyleSheet
|
|
4
|
+
} from 'react-native';
|
|
5
|
+
import moment from 'moment';
|
|
6
|
+
import {
|
|
7
|
+
Text, Icon, Colors
|
|
8
|
+
} from '@momo-kits/core';
|
|
9
|
+
import Util from './Util';
|
|
10
|
+
|
|
11
|
+
const HeaderControl = forwardRef(({ onPressBackArrow, onPressNextArrow, selectedDate }, ref) => {
|
|
12
|
+
const [info, setInfo] = useState({
|
|
13
|
+
date: moment(selectedDate || new Date())
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
useImperativeHandle(ref, () => ({
|
|
17
|
+
onUpdateInfo
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
const onUpdateInfo = (date) => {
|
|
21
|
+
setInfo(date);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if (info && info.date) {
|
|
25
|
+
const headerFormat = `${Util.mapMonth(info.date.month() + 1)}/${info.date.year()}`;
|
|
26
|
+
return (
|
|
27
|
+
<View style={styles.container}>
|
|
28
|
+
<TouchableOpacity
|
|
29
|
+
style={styles.btnLeft}
|
|
30
|
+
onPress={onPressBackArrow}
|
|
31
|
+
>
|
|
32
|
+
<Icon name="24_arrow_chevron_left_small" tintColor={Colors.black_17} style={styles.icon} />
|
|
33
|
+
</TouchableOpacity>
|
|
34
|
+
<Text.H4 style={styles.txtHeader}>
|
|
35
|
+
{headerFormat}
|
|
36
|
+
</Text.H4>
|
|
37
|
+
<TouchableOpacity
|
|
38
|
+
style={styles.btnRight}
|
|
39
|
+
onPress={onPressNextArrow}
|
|
40
|
+
>
|
|
41
|
+
<Icon name="24_arrow_chevron_right_small" tintColor={Colors.black_17} style={styles.icon} />
|
|
42
|
+
</TouchableOpacity>
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return <View />;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default HeaderControl;
|
|
50
|
+
const styles = StyleSheet.create({
|
|
51
|
+
icon: { width: 24, height: 24, resizeMode: 'contain' },
|
|
52
|
+
txtHeader: {
|
|
53
|
+
// fontSize: 15,
|
|
54
|
+
lineHeight: 19,
|
|
55
|
+
fontWeight: 'bold',
|
|
56
|
+
textAlign: 'center',
|
|
57
|
+
color: Colors.black_17
|
|
58
|
+
},
|
|
59
|
+
btnRight: {
|
|
60
|
+
width: 36,
|
|
61
|
+
height: 36,
|
|
62
|
+
justifyContent: 'center',
|
|
63
|
+
alignItems: 'center'
|
|
64
|
+
},
|
|
65
|
+
btnLeft: {
|
|
66
|
+
width: 36,
|
|
67
|
+
height: 36,
|
|
68
|
+
justifyContent: 'center',
|
|
69
|
+
alignItems: 'center'
|
|
70
|
+
},
|
|
71
|
+
container: {
|
|
72
|
+
height: 36,
|
|
73
|
+
flexDirection: 'row',
|
|
74
|
+
justifyContent: 'space-between',
|
|
75
|
+
backgroundColor: '#edf6fe',
|
|
76
|
+
alignItems: 'center',
|
|
77
|
+
borderRadius: 4
|
|
78
|
+
},
|
|
79
|
+
});
|
|
@@ -1 +1,191 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable func-names */
|
|
2
|
+
/* eslint-disable no-bitwise */
|
|
3
|
+
function Lunar() {
|
|
4
|
+
this.isleap = false;
|
|
5
|
+
this.lunarDay = 0;
|
|
6
|
+
this.lunarMonth = 0;
|
|
7
|
+
this.lunarYear = 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Solar() {
|
|
11
|
+
this.solarDay = 0;
|
|
12
|
+
this.solarMonth = 0;
|
|
13
|
+
this.solarYear = 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function LunarSolarConverter() {
|
|
17
|
+
this.lunar_month_days = [1887, 0x1694, 0x16aa, 0x4ad5,
|
|
18
|
+
0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a, 0xd54, 0x75aa, 0x156a,
|
|
19
|
+
0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4,
|
|
20
|
+
0x135a, 0x495d, 0x95c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8,
|
|
21
|
+
0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a,
|
|
22
|
+
0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94,
|
|
23
|
+
0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a,
|
|
24
|
+
0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b,
|
|
25
|
+
0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57,
|
|
26
|
+
0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae,
|
|
27
|
+
0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d,
|
|
28
|
+
0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da,
|
|
29
|
+
0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4,
|
|
30
|
+
0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65,
|
|
31
|
+
0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a,
|
|
32
|
+
0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694,
|
|
33
|
+
0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526,
|
|
34
|
+
0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c,
|
|
35
|
+
0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a,
|
|
36
|
+
0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936,
|
|
37
|
+
0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e,
|
|
38
|
+
0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c,
|
|
39
|
+
0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4,
|
|
40
|
+
0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa,
|
|
41
|
+
0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa,
|
|
42
|
+
0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54,
|
|
43
|
+
0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4,
|
|
44
|
+
0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a,
|
|
45
|
+
0x136a5, 0xda4, 0x15ac];
|
|
46
|
+
|
|
47
|
+
this.solar_1_1 = [1887, 0xec04c, 0xec23f, 0xec435, 0xec649,
|
|
48
|
+
0xec83e, 0xeca51, 0xecc46, 0xece3a, 0xed04d, 0xed242, 0xed436,
|
|
49
|
+
0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244,
|
|
50
|
+
0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052,
|
|
51
|
+
0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41,
|
|
52
|
+
0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d,
|
|
53
|
+
0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a,
|
|
54
|
+
0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848,
|
|
55
|
+
0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636,
|
|
56
|
+
0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443,
|
|
57
|
+
0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f,
|
|
58
|
+
0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e,
|
|
59
|
+
0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b,
|
|
60
|
+
0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39,
|
|
61
|
+
0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46,
|
|
62
|
+
0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853,
|
|
63
|
+
0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641,
|
|
64
|
+
0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e,
|
|
65
|
+
0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c,
|
|
66
|
+
0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a,
|
|
67
|
+
0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37,
|
|
68
|
+
0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44,
|
|
69
|
+
0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51,
|
|
70
|
+
0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841,
|
|
71
|
+
0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438,
|
|
72
|
+
0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051,
|
|
73
|
+
0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b,
|
|
74
|
+
0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845,
|
|
75
|
+
0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d,
|
|
76
|
+
0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038,
|
|
77
|
+
0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f,
|
|
78
|
+
0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849,
|
|
79
|
+
0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444,
|
|
80
|
+
0x107638, 0x10784c, 0x107a3f, 0x107c53, 0x107e48];
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @return {number}
|
|
84
|
+
*/
|
|
85
|
+
this.GetBitInt = function (data, length, shift) {
|
|
86
|
+
return (data & (((1 << length) - 1) << shift)) >> shift;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// WARNING: Dates before Oct. 1582 are inaccurate
|
|
90
|
+
/**
|
|
91
|
+
* @return {number}
|
|
92
|
+
*/
|
|
93
|
+
this.SolarToInt = function (y, m, d) {
|
|
94
|
+
m = (m + 9) % 12;
|
|
95
|
+
y = parseInt(y) - parseInt(m / 10);
|
|
96
|
+
return 365 * y + parseInt(y / 4) - parseInt(y / 100) + parseInt(y / 400) + parseInt((m * 306 + 5) / 10)
|
|
97
|
+
+ (d - 1);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
this.SolarFromInt = function (g) {
|
|
101
|
+
let y = parseInt((10000 * g + 14780) / 3652425);
|
|
102
|
+
let ddd = g - (365 * y + parseInt(y / 4) - parseInt(y / 100) + parseInt(y / 400));
|
|
103
|
+
if (ddd < 0) {
|
|
104
|
+
y--;
|
|
105
|
+
ddd = g - (365 * y + parseInt(y / 4) - parseInt(y / 100) + parseInt(y / 400));
|
|
106
|
+
}
|
|
107
|
+
const mi = parseInt((100 * ddd + 52) / 3060);
|
|
108
|
+
const mm = (mi + 2) % 12 + 1;
|
|
109
|
+
y += parseInt((mi + 2) / 12);
|
|
110
|
+
const dd = ddd - parseInt((mi * 306 + 5) / 10) + 1;
|
|
111
|
+
const solar = new Solar();
|
|
112
|
+
solar.solarYear = parseInt(y);
|
|
113
|
+
solar.solarMonth = parseInt(mm);
|
|
114
|
+
solar.solarDay = parseInt(dd);
|
|
115
|
+
return solar;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
this.LunarToSolar = function (lunar) {
|
|
119
|
+
const days = this.lunar_month_days[lunar.lunarYear - this.lunar_month_days[0]];
|
|
120
|
+
const leap = this.GetBitInt(days, 4, 13);
|
|
121
|
+
let offset = 0;
|
|
122
|
+
let loopend = leap;
|
|
123
|
+
if (!lunar.isleap) {
|
|
124
|
+
if (lunar.lunarMonth <= leap || leap === 0) {
|
|
125
|
+
loopend = lunar.lunarMonth - 1;
|
|
126
|
+
} else {
|
|
127
|
+
loopend = lunar.lunarMonth;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (let i = 0; i < loopend; i++) {
|
|
131
|
+
offset += this.GetBitInt(days, 1, 12 - i) === 1 ? 30 : 29;
|
|
132
|
+
}
|
|
133
|
+
offset += lunar.lunarDay;
|
|
134
|
+
|
|
135
|
+
const solar11 = this.solar_1_1[lunar.lunarYear - this.solar_1_1[0]];
|
|
136
|
+
|
|
137
|
+
const y = this.GetBitInt(solar11, 12, 9);
|
|
138
|
+
const m = this.GetBitInt(solar11, 4, 5);
|
|
139
|
+
const d = this.GetBitInt(solar11, 5, 0);
|
|
140
|
+
|
|
141
|
+
return this.SolarFromInt(this.SolarToInt(y, m, d) + offset - 1);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
this.SolarToLunar = function (solar) {
|
|
145
|
+
const lunar = new Lunar();
|
|
146
|
+
let index = solar.solarYear - this.solar_1_1[0];
|
|
147
|
+
const data = (solar.solarYear << 9) | (solar.solarMonth << 5)
|
|
148
|
+
| (solar.solarDay);
|
|
149
|
+
if (this.solar_1_1[index] > data) {
|
|
150
|
+
index--;
|
|
151
|
+
}
|
|
152
|
+
const solar11 = this.solar_1_1[index];
|
|
153
|
+
const y = this.GetBitInt(solar11, 12, 9);
|
|
154
|
+
const m = this.GetBitInt(solar11, 4, 5);
|
|
155
|
+
const d = this.GetBitInt(solar11, 5, 0);
|
|
156
|
+
let offset = this.SolarToInt(solar.solarYear, solar.solarMonth,
|
|
157
|
+
solar.solarDay) - this.SolarToInt(y, m, d);
|
|
158
|
+
|
|
159
|
+
const days = this.lunar_month_days[index];
|
|
160
|
+
const leap = this.GetBitInt(days, 4, 13);
|
|
161
|
+
|
|
162
|
+
const lunarY = index + this.solar_1_1[0];
|
|
163
|
+
let lunarM = 1;
|
|
164
|
+
offset += 1;
|
|
165
|
+
|
|
166
|
+
for (let i = 0; i < 13; i++) {
|
|
167
|
+
const dm = this.GetBitInt(days, 1, 12 - i) === 1 ? 30 : 29;
|
|
168
|
+
if (offset > dm) {
|
|
169
|
+
lunarM++;
|
|
170
|
+
offset -= dm;
|
|
171
|
+
} else {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const lunarD = parseInt(offset);
|
|
176
|
+
lunar.lunarYear = lunarY;
|
|
177
|
+
lunar.lunarMonth = lunarM;
|
|
178
|
+
lunar.isleap = false;
|
|
179
|
+
if (leap !== 0 && lunarM > leap) {
|
|
180
|
+
lunar.lunarMonth = lunarM - 1;
|
|
181
|
+
if (lunarM === leap + 1) {
|
|
182
|
+
lunar.isleap = true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
lunar.lunarDay = lunarD;
|
|
187
|
+
return lunar;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
module.exports = LunarSolarConverter;
|
package/src/LunarService.js
CHANGED
|
@@ -1 +1,185 @@
|
|
|
1
|
-
|
|
1
|
+
const removeFractionalPart = number => parseInt(number);
|
|
2
|
+
|
|
3
|
+
/* Compute the (integral) Julian day number of day dd/mm/yyyy, i.e., the number
|
|
4
|
+
* of days between 1/1/4713 BC (Julian calendar) and dd/mm/yyyy.
|
|
5
|
+
* Formula from http://www.tondering.dk/claus/calendar.html
|
|
6
|
+
*/
|
|
7
|
+
const jdFromDate = (dd, mm, yy) => {
|
|
8
|
+
let a, y, m, jd;
|
|
9
|
+
a = removeFractionalPart((14 - mm) / 12);
|
|
10
|
+
y = yy + 4800 - a;
|
|
11
|
+
m = mm + 12 * a - 3;
|
|
12
|
+
jd = dd + removeFractionalPart((153 * m + 2) / 5) + 365 * y + removeFractionalPart(y / 4) - removeFractionalPart(y / 100) +
|
|
13
|
+
removeFractionalPart(y / 400) - 32045;
|
|
14
|
+
if (jd < 2299161) {
|
|
15
|
+
jd = dd + removeFractionalPart((153 * m + 2) / 5) + 365 * y + removeFractionalPart(y / 4) - 32083;
|
|
16
|
+
}
|
|
17
|
+
return jd;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Convert a Julian day number to day/month/year. Parameter jd is an integer */
|
|
21
|
+
const jdToDate = (jd) => {
|
|
22
|
+
let a, b, c, d, e, m, day, month, year;
|
|
23
|
+
if (jd > 2299160) { // After 5/10/1582, Gregorian calendar
|
|
24
|
+
a = jd + 32044;
|
|
25
|
+
b = removeFractionalPart((4 * a + 3) / 146097);
|
|
26
|
+
c = a - removeFractionalPart((b * 146097) / 4);
|
|
27
|
+
} else {
|
|
28
|
+
b = 0;
|
|
29
|
+
c = jd + 32082;
|
|
30
|
+
}
|
|
31
|
+
d = removeFractionalPart((4 * c + 3) / 1461);
|
|
32
|
+
e = c - removeFractionalPart((1461 * d) / 4);
|
|
33
|
+
m = removeFractionalPart((5 * e + 2) / 153);
|
|
34
|
+
day = e - removeFractionalPart((153 * m + 2) / 5) + 1;
|
|
35
|
+
month = m + 3 - 12 * removeFractionalPart(m / 10);
|
|
36
|
+
year = b * 100 + d - 4800 + removeFractionalPart(m / 10);
|
|
37
|
+
return [day, month, year];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Compute the time of the k-th new moon after the new moon of 1/1/1900 13:52 UCT
|
|
41
|
+
* (measured as the number of days since 1/1/4713 BC noon UCT, e.g., 2451545.125 is 1/1/2000 15:00 UTC).
|
|
42
|
+
* Returns a floating number, e.g., 2415079.9758617813 for k=2 or 2414961.935157746 for k=-2
|
|
43
|
+
* Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
|
|
44
|
+
*/
|
|
45
|
+
const NewMoon = (k) => {
|
|
46
|
+
let T, T2, T3, dr, Jd1, M, Mpr, F, C1, deltat, JdNew;
|
|
47
|
+
T = k / 1236.85; // Time in Julian centuries from 1900 January 0.5
|
|
48
|
+
T2 = T * T;
|
|
49
|
+
T3 = T2 * T;
|
|
50
|
+
dr = Math.PI / 180;
|
|
51
|
+
Jd1 = 2415020.75933 + 29.53058868 * k + 0.0001178 * T2 - 0.000000155 * T3;
|
|
52
|
+
Jd1 = Jd1 + 0.00033 *
|
|
53
|
+
Math.sin((166.56 + 132.87 * T - 0.009173 * T2) * dr); // Mean new moon
|
|
54
|
+
M = 359.2242 + 29.10535608 * k - 0.0000333 * T2 -
|
|
55
|
+
0.00000347 * T3; // Sun's mean anomaly
|
|
56
|
+
Mpr = 306.0253 + 385.81691806 * k + 0.0107306 * T2 +
|
|
57
|
+
0.00001236 * T3; // Moon's mean anomaly
|
|
58
|
+
F = 21.2964 + 390.67050646 * k - 0.0016528 * T2 -
|
|
59
|
+
0.00000239 * T3; // Moon's argument of latitude
|
|
60
|
+
C1 = (0.1734 - 0.000393 * T) * Math.sin(M * dr) + 0.0021 * Math.sin(2 * dr * M);
|
|
61
|
+
C1 = C1 - 0.4068 * Math.sin(Mpr * dr) + 0.0161 * Math.sin(dr * 2 * Mpr);
|
|
62
|
+
C1 = C1 - 0.0004 * Math.sin(dr * 3 * Mpr);
|
|
63
|
+
C1 = C1 + 0.0104 * Math.sin(dr * 2 * F) - 0.0051 * Math.sin(dr * (M + Mpr));
|
|
64
|
+
C1 = C1 - 0.0074 * Math.sin(dr * (M - Mpr)) + 0.0004 * Math.sin(dr * (2 * F + M));
|
|
65
|
+
C1 = C1 - 0.0004 * Math.sin(dr * (2 * F - M)) - 0.0006 * Math.sin(dr * (2 * F + Mpr));
|
|
66
|
+
C1 = C1 + 0.0010 * Math.sin(dr * (2 * F - Mpr)) + 0.0005 * Math.sin(dr * (2 * Mpr + M));
|
|
67
|
+
if (T < -11) {
|
|
68
|
+
deltat = 0.001 + 0.000839 * T + 0.0002261 * T2 - 0.00000845 * T3 -
|
|
69
|
+
0.000000081 * T * T3;
|
|
70
|
+
} else {
|
|
71
|
+
deltat = -0.000278 + 0.000265 * T + 0.000262 * T2;
|
|
72
|
+
}
|
|
73
|
+
JdNew = Jd1 + C1 - deltat;
|
|
74
|
+
return JdNew;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Compute the longitude of the sun at any time.
|
|
78
|
+
* Parameter: floating number jdn, the number of days since 1/1/4713 BC noon
|
|
79
|
+
* Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
|
|
80
|
+
*/
|
|
81
|
+
const SunLongitude = (jdn) => {
|
|
82
|
+
let T, T2, dr, M, L0, DL, L;
|
|
83
|
+
T = (jdn - 2451545.0) /
|
|
84
|
+
36525; // Time in Julian centuries from 2000-01-01 12:00:00 GMT
|
|
85
|
+
T2 = T * T;
|
|
86
|
+
dr = Math.PI / 180; // degree to radian
|
|
87
|
+
M = 357.52910 + 35999.05030 * T - 0.0001559 * T2 -
|
|
88
|
+
0.00000048 * T * T2; // mean anomaly, degree
|
|
89
|
+
L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T2; // mean longitude, degree
|
|
90
|
+
DL = (1.914600 - 0.004817 * T - 0.000014 * T2) * Math.sin(dr * M);
|
|
91
|
+
DL = DL + (0.019993 - 0.000101 * T) * Math.sin(dr * 2 * M) +
|
|
92
|
+
0.000290 * Math.sin(dr * 3 * M);
|
|
93
|
+
L = L0 + DL; // true longitude, degree
|
|
94
|
+
L = L * dr;
|
|
95
|
+
L = L - Math.PI * 2 * (Math.sin(L / (Math.PI * 2))); // Normalize to (0, 2*PI)
|
|
96
|
+
return L;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Compute sun position at midnight of the day with the given Julian day number.
|
|
100
|
+
* The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00.
|
|
101
|
+
* The returns a number between 0 and 11.
|
|
102
|
+
* From the day after March equinox and the 1st major term after March equinox, 0 is returned.
|
|
103
|
+
* After that, return 1, 2, 3 ...
|
|
104
|
+
*/
|
|
105
|
+
const getSunLongitude = (dayNumber, timeZone) => {
|
|
106
|
+
return removeFractionalPart(SunLongitude(dayNumber - 0.5 - timeZone / 24) / Math.PI * 6);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Compute the day of the k-th new moon in the given time zone.
|
|
110
|
+
* The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00
|
|
111
|
+
*/
|
|
112
|
+
const getNewMoonDay = (k, timeZone) => {
|
|
113
|
+
return removeFractionalPart(NewMoon(k) + 0.5 + timeZone / 24);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Find the day that starts the luner month 11 of the given year for the given time zone */
|
|
117
|
+
const getLunarMonth11 = (yy, timeZone) => {
|
|
118
|
+
let k, off, nm, sunLong;
|
|
119
|
+
//off = jdFromDate(31, 12, yy) - 2415021.076998695;
|
|
120
|
+
off = jdFromDate(31, 12, yy) - 2415021;
|
|
121
|
+
k = removeFractionalPart(off / 29.530588853);
|
|
122
|
+
nm = getNewMoonDay(k, timeZone);
|
|
123
|
+
sunLong = getSunLongitude(nm, timeZone); // sun longitude at local midnight
|
|
124
|
+
if (sunLong >= 9) {
|
|
125
|
+
nm = getNewMoonDay(k - 1, timeZone);
|
|
126
|
+
}
|
|
127
|
+
return nm;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Find the index of the leap month after the month starting on the day a11. */
|
|
131
|
+
const getLeapMonthOffset = (a11, timeZone) => {
|
|
132
|
+
let k, last, arc, i;
|
|
133
|
+
k = removeFractionalPart((a11 - 2415021.076998695) / 29.530588853 + 0.5);
|
|
134
|
+
last = 0;
|
|
135
|
+
i = 1; // We start with the month following lunar month 11
|
|
136
|
+
arc = getSunLongitude(getNewMoonDay(k + i, timeZone), timeZone);
|
|
137
|
+
do {
|
|
138
|
+
last = arc;
|
|
139
|
+
i++;
|
|
140
|
+
arc = getSunLongitude(getNewMoonDay(k + i, timeZone), timeZone);
|
|
141
|
+
} while (arc !== last && i < 14);
|
|
142
|
+
return i - 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Comvert solar date dd/mm/yyyy to the corresponding lunar date */
|
|
146
|
+
export const convertSolar2Lunar = (dd, mm, yy, timeZone) => {
|
|
147
|
+
let k, dayNumber, monthStart, a11, b11, lunarDay, lunarMonth, lunarYear,
|
|
148
|
+
lunarLeap;
|
|
149
|
+
dayNumber = jdFromDate(dd, mm, yy);
|
|
150
|
+
k = removeFractionalPart((dayNumber - 2415021.076998695) / 29.530588853);
|
|
151
|
+
monthStart = getNewMoonDay(k + 1, timeZone);
|
|
152
|
+
if (monthStart > dayNumber) {
|
|
153
|
+
monthStart = getNewMoonDay(k, timeZone);
|
|
154
|
+
}
|
|
155
|
+
//alert(dayNumber+" -> "+monthStart);
|
|
156
|
+
a11 = getLunarMonth11(yy, timeZone);
|
|
157
|
+
b11 = a11;
|
|
158
|
+
if (a11 >= monthStart) {
|
|
159
|
+
lunarYear = yy;
|
|
160
|
+
a11 = getLunarMonth11(yy - 1, timeZone);
|
|
161
|
+
} else {
|
|
162
|
+
lunarYear = yy + 1;
|
|
163
|
+
b11 = getLunarMonth11(yy + 1, timeZone);
|
|
164
|
+
}
|
|
165
|
+
lunarDay = dayNumber - monthStart + 1;
|
|
166
|
+
let diff = removeFractionalPart((monthStart - a11) / 29);
|
|
167
|
+
lunarLeap = 0;
|
|
168
|
+
lunarMonth = diff + 10;
|
|
169
|
+
if (b11 - a11 > 365) {
|
|
170
|
+
let leapMonthDiff = getLeapMonthOffset(a11, timeZone);
|
|
171
|
+
if (diff >= leapMonthDiff) {
|
|
172
|
+
lunarMonth = diff + 10;
|
|
173
|
+
if (diff === leapMonthDiff) {
|
|
174
|
+
lunarLeap = 1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (lunarMonth > 12) {
|
|
179
|
+
lunarMonth = lunarMonth - 12;
|
|
180
|
+
}
|
|
181
|
+
if (lunarMonth >= 11 && diff < 4) {
|
|
182
|
+
lunarYear -= 1;
|
|
183
|
+
}
|
|
184
|
+
return { lunarDay, lunarMonth: lunarMonth, lunarYear, isleap: lunarLeap};
|
|
185
|
+
}
|