``
```<template>
<view class="calendar">
<view class="week">
<view class="item" wx:for="{{weekList}}" wx:key="item">{{ item }}</view>
</view>
<view class="day">
<view class="item {{currentDay==item.solar?'active':''}}" wx:for="{{dayList}}" wx:key="index">
<view class="num">{{ item.solar }}</view>
<view class="tip">{{ item.lunar }}</view>
</view>
</view>
</view>
</template>
<script>
import { createComponent } from '@mpxjs/core'
import { getLunarBySolar } from '../../utils/SolarToLunar'
createComponent({
properties: {
day: {
type: String,
value: new Date()
}
},
data: {
weekList: ['日', '一', '二', '三', '四', '五', '六'],
dayList: [],
currentDay: 1
},
watch: {
day(newVal, oldVal) {
let current = new Date(newVal)
this.currentDay = current.getDate()
let date = new Date(current.getFullYear(), current.getMonth(), 1)
let week = date.getDay()
this.dayList = []
for (let i = 0; i < week; i++) {
this.dayList.push({
solar: '',
lunar: ''
})
}
let dayCount = new Date(current.getFullYear(), current.getMonth() + 1, 0).getDate()
for (let i = 1; i <= dayCount; i++) {
if (i > 1) date.setDate(date.getDate() + 1)
this.dayList.push({
solar: i,
lunar: getLunarBySolar(date)
})
}
}
}
})
</script>
<style lang="scss" scoped>
.calendar {
padding: 30rpx;
.week {
display: flex;
.item {
width: 98rpx;
height: 60rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24rpx;
color: #5a5f6b;
letter-spacing: 0;
text-align: center;
line-height: 60rpx;
}
}
.day {
display: flex;
flex-wrap: wrap;
.item {
width: 98rpx;
text-align: center;
.num {
height: 66rpx;
font-family: PingFangSC-SNaNrpxibold;
font-weight: 600;
font-size: 36rpx;
color: #222222;
letter-spacing: 0;
text-align: center;
line-height: 66rpx;
}
.tip {
height: 46rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 20rpx;
color: #aaaaaa;
letter-spacing: 0;
text-align: center;
}
}
.active {
width: 98rpx;
background: #661eff;
border-radius: 30rpx;
.num {
color: #ffffff;
}
.tip {
color: #ffffff;
}
}
}
}
</style>
农历日历互转方法
```js
```const mArr = [
"春节",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
];
const dArr = [
"初二",
"初三",
"初四",
"初五",
"初六",
"初七",
"初八",
"初九",
"初十",
"十一",
"十二",
"十三",
"十四",
"十五",
"十六",
"十七",
"十八",
"十九",
"二十",
"廿一",
"廿一",
"廿一",
"廿一",
"廿一",
"廿一",
"廿一",
"廿一",
"廿一",
"三十",
];
/**
* 根据农历获取阳历
* @see https://blog.csdn.net/zhangjiaqianghh/article/details/115478404
* @param {农历日期, 2022-01-01} lunar
* @param {是否闰月, false} leapMonthFlag
* @return {阳历日期, 2022-02-01} newDate
*/
export const getSolarByLunar = (lunar, leapMonthFlag) => {
// 使用//g正则替换所有
var lunarDt = lunar.replace(/-/g, "");
var lunarYear = parseInt(lunarDt.substring(0, 4));
var lunarMonth = parseInt(lunarDt.substring(4, 6));
var lunarDay = parseInt(lunarDt.substring(6, 8));
checkLunarDate(lunarYear, lunarMonth, lunarDay, leapMonthFlag);
var offset = 0;
for (var i = 1900; i < lunarYear; i++) {
var yearDaysCount = getYearDays(i); // 求阴历某年天数
offset += yearDaysCount;
}
var leapMonth = getLeapMonth(lunarYear);
//当年没有闰月或月份早于闰月或和闰月同名的月份
if (
leapMonth == 0 ||
lunarMonth < leapMonth ||
!leapMonthFlag & (lunarMonth == leapMonth)
) {
for (var i = 1; i < lunarMonth; i++) {
var tempMonthDaysCount = getMonthDays(lunarYear, i);
offset += tempMonthDaysCount;
}
// 检查日期是否大于最大天
if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
console.error("不合法的农历日期!");
}
offset += lunarDay; // 加上当月的天数
} else {
console.log("当年有闰月,且月份晚于或等于闰月======" + leapMonth);
//当年有闰月,且月份晚于或等于闰月
for (var i = 1; i < lunarMonth; i++) {
var tempMonthDaysCount = getMonthDays(lunarYear, i);
offset += tempMonthDaysCount;
}
if (lunarMonth > leapMonth) {
var temp = getLeapMonthDays(lunarYear); // 计算闰月天数
offset += temp; // 加上闰月天数
if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
throw new Exception("不合法的农历日期!");
}
offset += lunarDay;
} else {
// 如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数
// 计算月为闰月
var temp = getMonthDays(lunarYear, lunarMonth); // 计算非闰月天数
offset += temp;
if (lunarDay > getLeapMonthDays(lunarYear)) {
throw new Exception("不合法的农历日期!");
}
offset += lunarDay;
}
}
// 阳历日期计算起点
var startStr = "1900-01-30";
var newDate = new Date(startStr);
newDate.setDate(newDate.getDate() + offset);
return newDate;
};
/**
* 根据阳历获取农历
* @see https://www.iteye.com/blog/lixor-1190599
* @param {当前日期} curDate
* @returns {int数组 [1,2]} result:索引1代表天数,索引2代表月份
*/
export const getLunarBySolar = (curDate) => {
var leapMonth = 0;
var date = new Date("1900/1/31");
// 求出当前时间和1900年1月31日相差的天数
var offset = parseInt((curDate.getTime() - date.getTime()) / 86400000);
// 用offset减去每农历年的天数,计算当天是农历第几天,i最终结果是农历的年份,offset是当年的第几天
var iYear,
daysOfYear = 0;
for (iYear = 1900; iYear < 2100 && offset > 0; iYear++) {
daysOfYear = getYearDays(iYear);
offset -= daysOfYear;
}
if (offset < 0) {
offset += daysOfYear;
iYear--;
}
// 闰哪个月,1-12
leapMonth = getLeapMonth(iYear);
var leap = false; // 默认值
// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
var iMonth,
daysOfMonth = 0;
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
// 闰月
if (leapMonth > 0 && iMonth == leapMonth + 1 && !leap) {
--iMonth;
leap = true;
daysOfMonth = getLeapMonthDays(iYear);
} else daysOfMonth = getMonthDays(iYear, iMonth);
offset -= daysOfMonth;
// 解除闰月
if (leap && iMonth == leapMonth + 1) leap = false;
}
// offset为0时,并且刚才计算的月份是闰月,要校正
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
if (leap) {
leap = false;
} else {
leap = true;
--iMonth;
}
}
// offset小于0时,也要校正
if (offset < 0) {
offset += daysOfMonth;
--iMonth;
}
// var result = [];
// result.push(iMonth);
// result.push(offset);
return numberToChinaDay(iMonth, offset);
};
const numberToChinaDay = (m, d) => {
return d == 0 ? mArr[m - 1] : dArr[d - 1];
};
const checkLunarDate = (lunarYear, lunarMonth, lunarDay, leapMonthFlag) => {
if (lunarYear < 1900 || lunarYear > 2100) {
console.error("非法年份" + lunarYear);
}
if (lunarMonth < 1 || lunarMonth > 12) {
console.error("非法月======" + lunarMonth);
}
if (lunarDay < 1 || lunarDay > 31) {
console.error("非法天======" + lunarDay);
}
//计算该年闰几月
var leapMonth = getLeapMonth(lunarYear);
if (leapMonthFlag & (leapMonth != lunarMonth)) {
// console.error("非润月======");
}
};
const getMonthDays = (lunarYeay, month) => {
if (month > 31 || month < 0) {
throw new Exception("月份有错!");
}
// 0X0FFFF[0000 {1111 1111 1111} 1111]中间12位代表12个月,1为大月,0为小月
var bit = 1 << (16 - month);
if ((lunarInfo[lunarYeay - 1900] & 0x0ffff & bit) == 0) {
return 29;
} else {
return 30;
}
};
const getLeapMonthDays = (year) => {
if (getLeapMonth(year) != 0) {
if ((lunarInfo[year - 1900] & 0xf0000) == 0) {
return 29;
} else {
return 30;
}
} else {
return 0;
}
};
const lunarInfo = [
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0,
0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540,
0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0,
0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2,
0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573,
0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4,
0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5,
0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46,
0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58,
0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50,
0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0,
0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,
0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0,
0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0,
0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,
];
const getYearDays = (y) => {
var i,
sum = 348;
for (i = 0x8000; i > 0x8; i >>= 1) {
if ((lunarInfo[y - 1900] & i) != 0) sum += 1;
}
return sum + leapDays(y);
};
const leapDays = (y) => {
if (getLeapMonth(y) != 0) {
if ((lunarInfo[y - 1900] & 0x10000) != 0) return 30;
else return 29;
} else return 0;
};
const getLeapMonth = (y) => {
return lunarInfo[y - 1900] & 0xf;
};