当前位置:网站首页>[wechat applet] lunar calendar and Gregorian calendar are mutually converted
[wechat applet] lunar calendar and Gregorian calendar are mutually converted
2022-07-27 09:22:00 【xun-ming】
List of articles
Source of demand
I wrote an article to get the lunar calendar date before ,【 Wechat applet 】 Get lunar calendar and week , Later, I thought of this small program 【TimeAssistant】 Medium “ Stay away from work ” Functional modules have to be optimized , The specific function interface is shown in the figure below

The original method of this function is to write the holiday date in the code , It's very inflexible to do so , The version must be updated at least once a year , If you can get this date dynamically , Wouldn't it be better .
Considering that these festivals are related to the lunar calendar , Like the Mid Autumn Festival 、 Dragon Boat Festival 、 Spring Festival , So I thought of writing a method , Pass in the lunar date to get the Gregorian date
Combat code
The core approach
/** * Get the Gregorian calendar according to the lunar calendar * @see https://blog.csdn.net/zhangjiaqianghh/article/details/115478404 * @param { Lunar date , 2022-01-01} lunar * @param { Leap month or not , false} leapMonthFlag * @return { Solar date , 2022-02-01} newDate */
const getSolarByLunar = (lunar,leapMonthFlag) => {
// Use //g Regular replace all
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); // Find the number of days in a certain year of the lunar calendar
offset += yearDaysCount;
}
var leapMonth = getLeapMonth(lunarYear);
// There is no leap month in that year, or the month is earlier than the leap month or the month with the same name as the leap month
if (leapMonth == 0 || (lunarMonth < leapMonth) || (!leapMonthFlag & lunarMonth == leapMonth)) {
for (var i = 1; i < lunarMonth; i++) {
var tempMonthDaysCount = getMonthDays(lunarYear, i);
offset += tempMonthDaysCount;
}
// Check whether the date is greater than the maximum day
if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
console.error(' Illegal lunar date !')
}
offset += lunarDay; // Add the number of days of the month
}else{
console.log(" There was a leap month , And the month is later than or equal to the leap month ======" + leapMonth);
// There was a leap month , And the month is later than or equal to the leap month
for (var i = 1; i < lunarMonth; i++) {
var tempMonthDaysCount = getMonthDays(lunarYear, i);
offset += tempMonthDaysCount;
}
if (lunarMonth > leapMonth) {
var temp = getLeapMonthDays(lunarYear); // Calculate leap month days
offset += temp; // Plus the number of leap months
if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
throw (new Exception(" Illegal lunar date !"));
}
offset += lunarDay;
} else {
// If you need to calculate leap months , You should first add the number of days of the normal month corresponding to the leap month
// The calculation month is leap month
var temp = getMonthDays(lunarYear, lunarMonth); // Calculate the number of non leap months
offset += temp;
if (lunarDay > getLeapMonthDays(lunarYear)) {
throw (new Exception(" Illegal lunar date !"));
}
offset += lunarDay;
}
}
// Starting point of solar calendar date calculation
var startStr = '1900-01-30';
var newDate =new Date(startStr);
newDate.setDate(newDate.getDate() + offset);
// console.log(" test 1======" + getZeroDate(newDate) +getWeekByDate(newDate));
return newDate;
}
/** * Get the lunar calendar according to the Gregorian calendar * @see https://www.iteye.com/blog/lixor-1190599 * @param { The current date } curDate * @returns {int Array [1,2]} result: Indexes 1 For days , Indexes 2 Represents the month */
const getLunarBySolar = curDate => {
var leapMonth = 0;
var date = new Date('1900/1/31');
// Find the current time and 1900 year 1 month 31 The number of days between days
var offset = parseInt( (curDate.getTime() - date.getTime()) / 86400000 );
// use offset Minus the number of days per calendar year , The day of calculation is the day of the lunar calendar ,i The end result is the year of the lunar calendar ,offset It was the first day of the year
var iYear, daysOfYear = 0;
for (iYear = 1900; iYear < 2100 && offset > 0; iYear++) {
daysOfYear = getYearDays(iYear);
offset -= daysOfYear;
}
if (offset < 0) {
offset += daysOfYear;
iYear--;
}
// Leap which month ,1-12
leapMonth = getLeapMonth(iYear);
var leap = false; // The default value is
// Using the days of the year offset, Subtract each month one by one ( Lunar calendar ) Days of , Find out the day of the month
var iMonth, daysOfMonth = 0;
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
// leap month
if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
--iMonth;
leap = true;
daysOfMonth = getLeapMonthDays(iYear);
} else
daysOfMonth = getMonthDays(iYear, iMonth);
offset -= daysOfMonth;
// Remove leap month
if (leap && iMonth == (leapMonth + 1))
leap = false;
}
// offset by 0 when , And the month just calculated is leap month , To correct
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
if (leap) {
leap = false;
} else {
leap = true;
--iMonth;
}
}
// offset Less than 0 when , Also need to correct
if (offset < 0) {
offset += daysOfMonth;
--iMonth;
}
var result = [];
result.push(chineseNumber[iMonth - 1]);
result.push(getChinaDayString(offset + 1));
return result;
}
Running effect
The following is the measured log diagram of the above two methods 

Tool method
1、 Check whether there is a problem with the lunar calendar date
const checkLunarDate = (lunarYear,lunarMonth,lunarDay,leapMonthFlag) =>{
if(lunarYear < 1900 || lunarYear > 2100){
console.error(" Illegal year " + lunarYear);
}
if(lunarMonth < 1 ||lunarMonth > 12){
console.error(" Illegal month ======" + lunarMonth);
}
if(lunarDay < 1 ||lunarDay > 31){
console.error(" Illegal day ======" + lunarDay);
}
// Calculate the leap months of the year
var leapMonth = getLeapMonth(lunarYear);
if (leapMonthFlag & leapMonth != lunarMonth) {
// console.error(" Non embellish the moon ======");
}
}
2, Calculate the leap months of the year
const getLeapMonth = year =>{
return (lunarInfo[year - 1900] & 0xf);
}
3, Get the number of days of a month in a leap year
const getMonthDays = (lunarYeay, month) =>{
if ((month > 31) || (month < 0)) {
throw (new Exception(" The month is wrong !"));
}
// 0X0FFFF[0000 {1111 1111 1111} 1111] middle 12 On behalf of 12 Months ,1 For the moon ,0 For Xiaoyue
var bit = 1 << (16 - month);
if (((lunarInfo[lunarYeay - 1900] & 0x0FFFF) & bit) == 0) {
return 29;
} else {
return 30;
}
}
4, Get leap month days
const getLeapMonthDays = year => {
if (getLeapMonth(year) != 0) {
if ((lunarInfo[year - 1900] & 0xf0000) == 0) {
return 29;
} else {
return 30;
}
} else {
return 0;
}
}
Other optimization
1, Calculate the day of the week in the Gregorian calendar , Calculate the days of this holiday , For example, Wednesday , It should only last for one day ; If it's Friday or Monday , Then it happened to be last Saturday and Sunday , Although such a calculation method is not very accurate , But you can basically guess
2, Qingming Festival is a special festival , It is not calculated according to the lunar calendar or the Gregorian calendar , But it's basically one of those days every year ; Labor Day is basically 5.1 To 5.5, but 2022 Year is special , from 4.30 Start 5 God , To sum up, it is subject to the announcement made by the holiday office
边栏推荐
- C language exercises
- The difference between computed and watch
- Intel, squeezed by Samsung and TSMC, finally put down its body to customize chip technology for Chinese chips
- pollFirst(),pollLast(),peekFirst(),peekLast()
- CUDA programming-02: first knowledge of CUDA Programming
- Nut joke based on arkui ETS
- The fourth day of learning C language
- ES6 new - object part
- 【CTF】ciscn_2019_es_2
- ES6 new - Operator extension
猜你喜欢

音乐体验天花板!14个网易云音乐的情感化设计细节

Pytorch custom CUDA operator tutorial and runtime analysis

Music experience ceiling! Emotional design details of 14 Netease cloud music

JS call and apply

ArcGIS pro2.8 deep learning environment configuration based on rtx30 graphics card

Antdesign a-modal自定义指令实现拖拽放大缩小

Special exercises for beginners of C language to learn code for the first time

1344. 时钟指针的夹角

HBuilder 微信小程序中运行uni-app项目

8 kinds of visual transformer finishing (Part 2)
随机推荐
BGP联邦实验
Data interaction based on restful pages
qt中使用sqlite同时打开多个数据库文件
[C language - zero basis _ study _ review _ lesson 5] operational properties of basic operators
Storage and computing engine
What if the parameters in QT are structs or custom classes when sending signals?
< script> detailed explanation of label content
6S parameters
Function anti chattering throttling
[acl2020] a novel method of component syntax tree serialization
C language exercises
音乐体验天花板!14个网易云音乐的情感化设计细节
Programming style
[C language - zero foundation lesson 10] adventure of array Kingdom
linux下安装oracle,本地PL/SQL连接Linux下的oracle导入表并新建用户和密码
[C language - zero foundation lesson 14] variable scope and storage class
Activation functions commonly used in deep learning
【微信小程序】农历公历互相转换
Easy language programming: allow the screen reading software to obtain the text of the label control
C language takes you to tear up the address book