提交 121397a1 authored 作者: pengxiaohui's avatar pengxiaohui

优化日历展示交互,新增快捷键今天,上一天,下一天快捷按钮,新增农历展示

上级 6973e60c
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<span v-for="item in weekList" :key="item">{{item}}</span> <span v-for="item in weekList" :key="item">{{item}}</span>
</div> </div>
<div class="calendar-day-list"> <div class="calendar-day-list">
<ul> <ul :class="{'range-selecting': rangeState.selecting}">
<li v-for="item in dayList" :key="item.getTime()" @click="selectDay(item)"> <li v-for="item in dayList" :key="item.getTime()" @click="selectDay(item)">
<div :class="getDayCellClasses(item)"> <div :class="getDayCellClasses(item)">
<span>{{item.getTime() === toDay ? '今' : item.getDate()}}</span> <span>{{item.getTime() === toDay ? '今' : item.getDate()}}</span>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
</div> </div>
</template> </template>
<script> <script>
import { dateFormat } from '@/utils/dateAlgs' import { dateFormat, getYMDByDate } from '@/utils/dateAlgs'
import getDays from './getDays' import getDays from './getDays'
export default { export default {
props: { props: {
...@@ -68,22 +68,14 @@ export default { ...@@ -68,22 +68,14 @@ export default {
type: { type: {
handler: function(nv) { handler: function(nv) {
if (nv) { if (nv) {
this.activeDate = '' this.init()
this.rangeState = {
endDate: null,
selecting: false
}
this.rangeStartDate = null
this.rangeEndDate = null
this.rangeDates = []
this.selectFirstDate = null
this.selectLastDate = null
} }
}, },
immediate: true immediate: true
}, },
defaultDate: { defaultDate: {
handler: function(nv, ov) { handler: function(nv, ov) {
this.init()
if (!nv) { if (!nv) {
const _date = new Date() const _date = new Date()
this.activeDate = '' this.activeDate = ''
...@@ -92,6 +84,7 @@ export default { ...@@ -92,6 +84,7 @@ export default {
if (Array.isArray(nv)) { if (Array.isArray(nv)) {
this.rangeStartDate = nv[0] this.rangeStartDate = nv[0]
this.rangeEndDate = nv[1] this.rangeEndDate = nv[1]
this.getRangeDates()
this.setMonthFirstDate(nv[0]) this.setMonthFirstDate(nv[0])
} else if (typeof nv === 'object' && this.type === 'date') { } else if (typeof nv === 'object' && this.type === 'date') {
this.setMonthFirstDate(nv) this.setMonthFirstDate(nv)
...@@ -106,6 +99,18 @@ export default { ...@@ -106,6 +99,18 @@ export default {
created() { created() {
}, },
methods: { methods: {
init() {
this.activeDate = ''
this.rangeState = {
endDate: null,
selecting: false
}
this.rangeStartDate = null
this.rangeEndDate = null
this.rangeDates = []
this.selectFirstDate = null
this.selectLastDate = null
},
getDayCellClasses(date) { getDayCellClasses(date) {
const classes = { const classes = {
grey: date.getMonth() !== this.activeMonth, grey: date.getMonth() !== this.activeMonth,
...@@ -161,29 +166,21 @@ export default { ...@@ -161,29 +166,21 @@ export default {
this.rangeEndDate = isReverse ? this.selectFirstDate : this.selectLastDate this.rangeEndDate = isReverse ? this.selectFirstDate : this.selectLastDate
this.getRangeDates() this.getRangeDates()
this.rangeState.selecting = false this.rangeState.selecting = false
this.$emit('change', [this.rangeStartDate, this.rangeEndDate]) this.$emit('change', { dates: [this.rangeStartDate, this.rangeEndDate], daysCount: this.rangeDates.length + 1 })
} }
} else { } else {
} }
}, },
getRangeDates() { getRangeDates() {
const sDate = this.rangeStartDate const sDate = getYMDByDate(this.rangeStartDate)
const eDate = this.rangeEndDate const eDate = getYMDByDate(this.rangeEndDate)
const sMonth = sDate.getMonth()
const eMonth = eDate.getMonth()
const sDay = sDate.getDate()
const eDay = eDate.getDate()
let rangeDayCount = 0
const datesArr = [] const datesArr = []
if (sMonth !== eMonth) { while ((eDate.getTime() - sDate.getTime()) > 0) {
const startMonthMaxDays = new Date(sDate.getFullYear(), sMonth + 1, 0).getDate() const year = sDate.getFullYear();
rangeDayCount = startMonthMaxDays - sDay + eDay - 1 const month = sDate.getMonth();
} else { const day = sDate.getDate();
rangeDayCount = eDay - sDay - 1 datesArr.push(new Date(year, month, day));
} sDate.setDate(day + 1);
for (let i = 0, day = sDay; i < rangeDayCount; i++) {
++day
datesArr.push(new Date(sDate.getFullYear(), sMonth, day))
} }
this.rangeDates = datesArr this.rangeDates = datesArr
}, },
...@@ -265,23 +262,33 @@ export default { ...@@ -265,23 +262,33 @@ export default {
} }
.calendar-day-list li .is-range, .calendar-day-list li .is-range,
.calendar-day-list li .start-date, .calendar-day-list li .start-date,
.calendar-day-list li .end-date{ .calendar-day-list li .end-date,
.calendar-day-list li .default,
.range-selecting li div:hover{
background-color: #f2f6fc; background-color: #f2f6fc;
} }
.calendar-day-list li .start-date{ .calendar-day-list li .start-date{
border-radius:12px 0 0 12px; border-radius:12px 0 0 12px;
margin-left: 2px;
} }
.calendar-day-list li .end-date{ .calendar-day-list li .end-date{
border-radius:0 12px 12px 0; border-radius:0 12px 12px 0;
margin-right: 2px;
} }
.calendar-day-list li .start-date.end-date{ .calendar-day-list li .start-date.end-date,
.calendar-day-list li .default,
.range-selecting li div:hover{
border-radius:12px; border-radius:12px;
margin:0 2px;
} }
.calendar-day-list li .current span, .calendar-day-list li .current span,
.calendar-day-list li .start-date span, .calendar-day-list li .start-date span,
.calendar-day-list li .end-date span, .calendar-day-list li .end-date span{
.calendar-day-list li .default span{
background-color: #409eff; background-color: #409eff;
color:#fff; color:#fff;
} }
.calendar-day-list li .default span, .range-selecting li:hover span{
background-color: rgba(64,158,255, .4);
color:#fff;
}
</style> </style>
\ No newline at end of file
...@@ -39,7 +39,7 @@ export default { ...@@ -39,7 +39,7 @@ export default {
// path: '/create-live' // path: '/create-live'
// }, // },
{ {
title: '日历列表', title: '直播日历',
icon: 'el-icon-date', icon: 'el-icon-date',
path: '/calendar' path: '/calendar'
}, },
......
...@@ -23,8 +23,19 @@ ...@@ -23,8 +23,19 @@
</div> </div>
<div class="right-container"> <div class="right-container">
<div class="top"> <div class="top">
<div class="title" v-if="tabActive === 'list'">{{defaultDate[0] | dateFormat}} - {{defaultDate[1] | dateFormat}}</div> <div class="top-left">
<div class="title" v-if="tabActive === 'day'">{{defaultDate | dateFormat}} {{defaultDate | dateFormat('星期{a}')}} </div> <el-button size="mini" round :disabled="isToday" @click="setToday">今天</el-button>
<el-button icon="el-icon-arrow-left" size="mini" circle @click="handleBtnClick('pre')"></el-button>
<el-button icon="el-icon-arrow-right" size="mini" circle @click="handleBtnClick('pre')"></el-button>
<div class="title" v-if="tabActive === 'list'">
{{defaultDate | dateRangeFormat}}
<p>农历 {{defaultDate | dateRangeToLunar}}</p>
</div>
<div class="title" v-if="tabActive === 'day'">
{{defaultDate | dateFormat}} {{defaultDate | dateFormat('星期{a}')}}
<p>农历 {{defaultDate | dateToLunar}}</p>
</div>
</div>
<el-radio-group v-model="tabActive" size="mini"> <el-radio-group v-model="tabActive" size="mini">
<el-radio-button label="list">列表</el-radio-button> <el-radio-button label="list">列表</el-radio-button>
<el-radio-button label="day"></el-radio-button> <el-radio-button label="day"></el-radio-button>
...@@ -42,7 +53,8 @@ ...@@ -42,7 +53,8 @@
import Calendar from '@/components/Calendar' import Calendar from '@/components/Calendar'
import List from './list/index' import List from './list/index'
import Day from './day/index.vue' import Day from './day/index.vue'
import { dateFormat } from '@/utils/dateAlgs' import { dateFormat, isSameDate } from '@/utils/dateAlgs'
import { getLunarDay } from '@/utils/lunarCalendar.js'
export default { export default {
data () { data () {
return { return {
...@@ -52,7 +64,8 @@ export default { ...@@ -52,7 +64,8 @@ export default {
}, },
tabActive: 'list', tabActive: 'list',
defaultDate: null, defaultDate: null,
dateType: 'date' dateType: 'date',
todayBtnDisabled: false
} }
}, },
components: { Calendar, List, Day }, components: { Calendar, List, Day },
...@@ -60,11 +73,59 @@ export default { ...@@ -60,11 +73,59 @@ export default {
now() { now() {
const now = new Date() const now = new Date()
return new Date(now.getFullYear(), now.getMonth(), now.getDate()) return new Date(now.getFullYear(), now.getMonth(), now.getDate())
},
isToday() {
let date = this.defaultDate
if (Array.isArray(this.defaultDate)) {
date = this.defaultDate[0]
}
return date && this.now.getTime() === date.getTime()
} }
}, },
filters: { filters: {
dateFormat (value, fmt) { dateFormat (value, fmt) {
return dateFormat(value, fmt || '{y}年{m}月{d}日') return dateFormat(value, fmt || '{y}年{m}月{d}日')
},
dateRangeFormat (value) {
let res
if (Array.isArray(value)) {
const sVal = value[0]
const eVal = value[1]
const sDateFormat = dateFormat(sVal, '{y}年{m}月{d}日')
if (isSameDate(sVal, eVal)) {
res = sDateFormat
} else if (dateFormat(sVal, '{y}年{m}') === dateFormat(eVal, '{y}年{m}')) {
res = sDateFormat + ' - ' + dateFormat(eVal, '{d}日')
} else if (dateFormat(sVal, '{y}年') === dateFormat(eVal, '{y}年')) {
res = sDateFormat + ' - ' + dateFormat(eVal, '{m}月{d}日')
} else {
res = sDateFormat + ' - ' + dateFormat(eVal, '{y}年{m}月{d}日')
}
}
return res
},
dateToLunar (val) {
const lunar = getLunarDay(val)
return `${lunar.month}月${lunar.day}`
},
dateRangeToLunar (value) {
let res
if (Array.isArray(value)) {
const sVal = value[0]
const eVal = value[1]
const sLunarDate = getLunarDay(sVal)
const eLunarDate = getLunarDay(eVal)
if (isSameDate(sVal, eVal)) {
res = `${sLunarDate.month}月${sLunarDate.day}`
} else if (sLunarDate.month === eLunarDate.month) {
res = `${sLunarDate.month}月${sLunarDate.day} - ${eLunarDate.day}`
} else if (sLunarDate.year === eLunarDate.year) {
res = `${sLunarDate.month}月${sLunarDate.day} - ${eLunarDate.month}月${eLunarDate.day}`
} else {
res = `${sLunarDate.year}年${sLunarDate.month}月${sLunarDate.day} - ${eLunarDate.year}年${eLunarDate.month}月${eLunarDate.day}`
}
}
return res
} }
}, },
watch: { watch: {
...@@ -86,7 +147,34 @@ export default { ...@@ -86,7 +147,34 @@ export default {
this.$router.push('/search') this.$router.push('/search')
}, },
calendarChange(val) { calendarChange(val) {
if (this.dateType === 'date') {
this.defaultDate = val this.defaultDate = val
} else {
this.defaultDate = val.dates
if (val.daysCount >= 60) {
this.$message.info('日期跨度不要超过六十天,以免查库速度过慢影响使用体验')
}
}
},
setToday() {
if (this.dateType === 'date') {
this.defaultDate = this.now
} else {
this.defaultDate = [this.now, this.now]
}
},
handleBtnClick(type) {
const num = type === 'pre' ? -1 : 1
if (this.dateType === 'date') {
this.defaultDate = this.datePlusMinus(this.defaultDate, num)
} else {
const start = this.datePlusMinus(this.defaultDate[0], num)
const end = this.datePlusMinus(this.defaultDate[1], num)
this.defaultDate = [start, end]
}
},
datePlusMinus(date, num) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + num)
} }
} }
} }
...@@ -164,9 +252,27 @@ h5{ ...@@ -164,9 +252,27 @@ h5{
flex-flow: row nowrap; flex-flow: row nowrap;
justify-content: space-between; justify-content: space-between;
} }
.right-container .top .top-left{
margin-left:10px;
}
.right-container .top .el-button{
line-height:14px;
height:28px;
}
.right-container .top .title{ .right-container .top .title{
text-indent:20px; text-indent:0px;
line-height:28px; line-height:12px;
font-size:14px;
color:#333;
display:inline-block;
vertical-align: middle;
margin-left:20px;
}
.right-container .top .title p{
line-height:22px;
font-size:12px;
transform:scale(0.9);
color: #606266;
} }
.left-calendar .bottom{ .left-calendar .bottom{
padding-left:4px; padding-left:4px;
......
<template> <template>
<div class="list"> <div class="list">
<el-table :data="listData" style="width: 100%" height="calc(100% - 32px)" v-loading="loading"> <el-table :data="listData" style="width: 100%" height="calc(100% - 32px)" v-loading="loading">
<el-table-column label="会议时间" min-width="160" align="center"> <el-table-column label="会议时间" min-width="215" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p style="color: #aeaeae"> <p style="color: #aeaeae">
<span style="font-size: 18px; color: #606266">{{ scope.row.start_time | dateFormat('{d}') }}</span> <span style="font-size: 18px; color: #606266">{{ scope.row.start_time | dateFormat('{d}') }}</span>
{{ scope.row.start_time | dateFormat('{m}月') }} {{ scope.row.start_time | dateFormat('周{a}') }} {{ scope.row.start_time | dateFormat('{m}月') }} {{ scope.row.start_time | dateFormat('周{a}') }}
<span style="font-size: 16px; color: #606266">{{ scope.row.start_time | dateFormat('{h}:{i}') }}</span> <span style="font-size: 16px; color: #606266">{{ scope.row.start_time | dateFormat('{h}:{i}') }}</span>
<span v-if="isSameDate(scope.row.start_time, scope.row.end_time)" style="font-size: 16px; color: #606266"> - {{ scope.row.end_time | dateFormat('{h}:{i}') }}</span>
</p> </p>
<p style="color: #aeaeae"> <p style="color: #aeaeae" v-if="!isSameDate(scope.row.start_time, scope.row.end_time)">
<span style="font-size: 18px; color: #606266">{{ scope.row.end_time | dateFormat('{d}') }}</span> <span style="font-size: 18px; color: #606266">{{ scope.row.end_time | dateFormat('{d}') }}</span>
{{ scope.row.end_time | dateFormat('{m}月') }} {{ scope.row.end_time | dateFormat('周{a}') }} {{ scope.row.end_time | dateFormat('{m}月') }} {{ scope.row.end_time | dateFormat('周{a}') }}
<span style="font-size: 16px; color: #606266">{{ scope.row.end_time | dateFormat('{h}:{i}') }}</span> <span style="font-size: 16px; color: #606266">{{ scope.row.end_time | dateFormat('{h}:{i}') }}</span>
...@@ -38,7 +39,7 @@ ...@@ -38,7 +39,7 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="resource" label="会议来源" width="80"></el-table-column> --> <!-- <el-table-column prop="resource" label="会议来源" width="80"></el-table-column> -->
<el-table-column prop="resource" label="会议状态" width="80" align="center"> <el-table-column prop="resource" label="会议状态" min-width="80" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p <p
:class="{ :class="{
...@@ -61,7 +62,7 @@ ...@@ -61,7 +62,7 @@
<el-pagination <el-pagination
:current-page.sync="curPage" :current-page.sync="curPage"
:page-size="pageSize" :page-size="pageSize"
layout="total, prev, pager, next" layout="total, prev, pager, next, jumper"
:total="total" :total="total"
@current-change="pageChange" @current-change="pageChange"
style="float: right" style="float: right"
...@@ -149,6 +150,9 @@ export default { ...@@ -149,6 +150,9 @@ export default {
// this.fetchMeetingList() // this.fetchMeetingList()
}, },
methods: { methods: {
isSameDate(start, end) {
return dateFormat(start, '{y}-{m}-{d}') === dateFormat(end, '{y}-{m}-{d}')
},
pageChange() { pageChange() {
this.fetchMeetingList() this.fetchMeetingList()
}, },
......
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="pageChange" style="float:right;"></el-pagination> <el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper" :total="total" @current-change="pageChange" style="float:right;"></el-pagination>
</div> </div>
</div> </div>
</template> </template>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="pageChange" style="float:right;"></el-pagination> <el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper" :total="total" @current-change="pageChange" style="float:right;"></el-pagination>
<el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="30%" center> <el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="30%" center>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" v-show="dialogType === 'add' || dialogType === 'edit'"> <el-form :model="form" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" v-show="dialogType === 'add' || dialogType === 'edit'">
<el-form-item label="ID" prop="userid" v-if="dialogType === 'edit'"> <el-form-item label="ID" prop="userid" v-if="dialogType === 'edit'">
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
</template> </template>
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="pageChange" style="float:right;"></el-pagination> <el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper" :total="total" @current-change="pageChange" style="float:right;"></el-pagination>
</div> </div>
</div> </div>
</template> </template>
......
/* 公历转农历代码思路:
1、建立农历年份查询表
2、计算输入公历日期与公历基准的相差天数
3、从农历基准开始遍历农历查询表,计算自农历基准之后每一年的天数,并用相差天数依次相减,确定农历年份
4、利用剩余相差天数以及农历每个月的天数确定农历月份
5、利用剩余相差天数确定农历哪一天 */
// 农历1949-2100年查询表
const lunarYearArr = [
0x0b557, // 1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
0x0d520 // 2100
]
const lunarMonth = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊']
const lunarDay = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初', '廿']
const tianGan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
const diZhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
// 计算农历年是否有闰月,参数为存储农历年的16进制
// 农历年份信息用16进制存储,其中16进制的最后1位可以用于判断是否有闰月
function hasLeapMonth(ly) {
// 获取16进制的最后1位,需要用到&与运算符
if (ly & 0xf) {
return ly & 0xf
} else {
return false
}
}
// 如果有闰月,计算农历闰月天数,参数为存储农历年的16进制
// 农历年份信息用16进制存储,其中16进制的第1位(0x除外)可以用于表示闰月是大月还是小月
function leapMonthDays(ly) {
if (hasLeapMonth(ly)) {
// 获取16进制的第1位(0x除外)
return ly & 0xf0000 ? 30 : 29
} else {
return 0
}
}
// 计算农历一年的总天数,参数为存储农历年的16进制
// 农历年份信息用16进制存储,其中16进制的第2-4位(0x除外)可以用于表示正常月是大月还是小月
function lunarYearDays(ly) {
let totalDays = 0
// 获取正常月的天数,并累加
// 获取16进制的第2-4位,需要用到>>移位运算符
for (let i = 0x8000; i > 0x8; i >>= 1) {
const monthDays = ly & i ? 30 : 29
totalDays += monthDays
}
// 如果有闰月,需要把闰月的天数加上
if (hasLeapMonth(ly)) {
totalDays += leapMonthDays(ly)
}
return totalDays
}
// 获取农历每个月的天数
// 参数需传入16进制数值
function lunarYearMonths(ly) {
const monthArr = []
// 获取正常月的天数,并添加到monthArr数组中
// 获取16进制的第2-4位,需要用到>>移位运算符
for (let i = 0x8000; i > 0x8; i >>= 1) {
monthArr.push(ly & i ? 30 : 29)
}
// 如果有闰月,需要把闰月的天数加上
if (hasLeapMonth(ly)) {
monthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly))
}
return monthArr
}
// 将农历年转换为天干,参数为农历年
function getTianGan(ly) {
let tianGanKey = (ly - 3) % 10
if (tianGanKey === 0) tianGanKey = 10
return tianGan[tianGanKey - 1]
}
// 将农历年转换为地支,参数为农历年
function getDiZhi(ly) {
let diZhiKey = (ly - 3) % 12
if (diZhiKey === 0) diZhiKey = 12
return diZhi[diZhiKey - 1]
}
// 公历转农历函数
function sloarToLunar(sy, sm, sd) {
// 输入的月份减1处理
sm -= 1
// 计算与公历基准的相差天数
// Date.UTC()返回的是距离公历1970年1月1日的毫秒数,传入的月份需要减1
let daySpan = (Date.UTC(sy, sm, sd) - Date.UTC(1949, 0, 29)) / (24 * 60 * 60 * 1000) + 1
let ly, lm, ld
// 确定输出的农历年份
for (let j = 0; j < lunarYearArr.length; j++) {
daySpan -= lunarYearDays(lunarYearArr[j])
if (daySpan <= 0) {
ly = 1949 + j
// 获取农历年份确定后的剩余天数
daySpan += lunarYearDays(lunarYearArr[j])
break
}
}
// 确定输出的农历月份
for (let k = 0; k < lunarYearMonths(lunarYearArr[ly - 1949]).length; k++) {
daySpan -= lunarYearMonths(lunarYearArr[ly - 1949])[k]
if (daySpan <= 0) {
// 有闰月时,月份的数组长度会变成13,因此,当闰月月份小于等于k时,lm不需要加1
if (hasLeapMonth(lunarYearArr[ly - 1949]) && hasLeapMonth(lunarYearArr[ly - 1949]) <= k) {
if (hasLeapMonth(lunarYearArr[ly - 1949]) < k) {
lm = k
} else if (hasLeapMonth(lunarYearArr[ly - 1949]) === k) {
lm = '闰' + k
} else {
lm = k + 1
}
} else {
lm = k + 1
}
// 获取农历月份确定后的剩余天数
daySpan += lunarYearMonths(lunarYearArr[ly - 1949])[k]
break
}
}
// 确定输出农历哪一天
ld = daySpan
// 将计算出来的农历月份转换成汉字月份,闰月需要在前面加上闰字
if (hasLeapMonth(lunarYearArr[ly - 1949]) && typeof lm === 'string' && lm.indexOf('闰') > -1) {
lm = `闰${lunarMonth[/\d/.exec(lm) - 1]}`
} else {
lm = lunarMonth[lm - 1]
}
// 将计算出来的农历年份转换为天干地支年
ly = getTianGan(ly) + getDiZhi(ly)
// 将计算出来的农历天数转换成汉字
if (ld < 11) {
ld = `${lunarDay[10]}${lunarDay[ld - 1]}`
} else if (ld > 10 && ld < 20) {
ld = `${lunarDay[9]}${lunarDay[ld - 11]}`
} else if (ld === 20) {
ld = `${lunarDay[1]}${lunarDay[9]}`
} else if (ld > 20 && ld < 30) {
ld = `${lunarDay[11]}${lunarDay[ld - 21]}`
} else if (ld === 30) {
ld = `${lunarDay[2]}${lunarDay[9]}`
}
return {
year: ly,
month: lm,
day: ld
}
}
// 通过日期获取农历
export function getLunarDay(date) {
if (typeof date === 'object' && date instanceof Date) {
return sloarToLunar(date.getFullYear(), date.getMonth() + 1, date.getDate())
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论