|
前端时间,公司需要一个日历控件,在网上看了很多 emmm,最终还是打算自己写一个,其实并不是很难,只是一些逻辑控制上需要耗费亦一些时间,下面是我制作日历控件时构思的逻辑,若有错误,还请指出:
下面是我做出的控件样式:

上面选择年份与月份的 是标题栏为一个类,下方显示日期的为一个类(三个按钮:回到今日,确定,取消 并非标题栏的控件)
首先说一说我在编写标题栏时一些逻辑以及问题:
这个标题栏的功能大概就是 设置一个最大年月,最小年月,当前显示年月,然后显示月份与年份
那么首先,我们需要记录最大最小年月
int mnMinYear;
int mnMinMonth;
int mnMaxYear;
int mnMaxMonth;
以及 当前年月
int mnYear;
int mnMonth;
那么减年份时,我们需要判断 mnYear-1 是否小于 mnMinYear
若是小于,则设置为最小年份。
若等于,那么判断当前的月份是否小于最小月份
若是小于最小月份 则等于最小月份
ps:假设最小年月为2017年9月,当前年月为 2018年8月,那么若是减年份时不判断月份,则会出现错误
下方给出代码:
void YearSubtract()
{
int nYear = mnYear - 1;
if(nYear < mnMinYear)
{
nYear = mnMinYear;
}
else if(nYear == mnMinYear)
{
if(mnMonth < mnMinMonth)
mnMonth = mnMinMonth;
mnYear = nYear;
emit Sig_DateChange(mnYear,mnMonth,1);
}
else
{
mnYear = nYear;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
那么下面就是 减少月份,减少月份的话
1.判断是否为最小年份 ,
是,则判断mnMonth-1 是否小于 最小月份 是则等于最小月份
否,则判断 mnMonth-1是否小于1 小于1 则等于12且调用YearSubtract()年份减
下方给出代码:
void MonthSubtract()
{
int nMonth = mnMonth - 1;
if(mnYear == mnMinYear)
{
if(nMonth < mnMinMonth)
{
mnMonth = mnMinMonth;
}
else
{
mnMonth = nMonth;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
else
{
if(nMonth < 1)
{
mnMonth = 12;
On_YearSubtract();
}
else
{
mnMonth = nMonth;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
}
下面就是 年份加:
1,判断 mnYear+1是否大于最大年份
是,则mnYear = mnMaxYear,再判断月份是否大于最大Date的月份,是,则mnMonth= mnMaxMonth,否,则不变
否,则 mnYear +=1,mnMonth 不变
下方给出代码:
void YearAdd()
{
int nYear = mnYear + 1;
if(nYear > mnMaxYear)
{
nYear = mnMaxYear;
}
else if(nYear == mnMaxYear)
{
if(mnMonth > mnMaxMonth)
mnMonth = mnMaxMonth;
mnYear = nYear;
emit Sig_DateChange(mnYear,mnMonth,1);
}
else
{
mnYear = nYear;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
接下来是 月份加:
1.首先判断当前年份是否为最大年份
是,则判断mnMonth+1 是否大于mnMaxMonth,是,则mnMonth =mnMaxMonth。否,则mnMonth +=1
否,则判断mnMonth+1是否大于12。是,则mnMonth = 1,调用YearAdd()。否,则mnMonth +=1
下方给出代码:
void MonthAdd()
{
int nMonth = mnMonth + 1;
if(mnYear == mnMaxYear)
{
if(nMonth > mnMaxMonth)
{
mnMonth = mnMaxMonth;
}
else
{
mnMonth = nMonth;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
else
{
if(nMonth > 12)
{
mnMonth = 1;
On_YearAdd();
}
else
{
mnMonth = nMonth;
emit Sig_DateChange(mnYear,mnMonth,1);
}
}
}
以上便是调节年月四个按钮的逻辑了 ,相信理解并不困难关键点在于月份的加减操作时,要注意此时的年份
如果没有最大日期,最小日期的限制话,删除mnMaxYear,mnMinYear判断,将mnMaxMonth换为12,mnMinMonth换为1即可
那么说完了标题栏的控件,就说明一下,当知道年月时,日期的显示问题
首先的问题 ,当前年月的第一天是周几 ,事实上网上已经有很多这种答案了 “蔡勒公式”即可 ,下面会给出WeekType()
那么还有就是 得到年月,得到当前年月的天数 ,这个逻辑倒也不难,下方会给出DayNumber()
int DayNumber(int nYear,int nMonth)
{
if(nMonth == 1 || nMonth == 3 || nMonth == 5 || nMonth == 7 || nMonth == 8 || nMonth == 10 || nMonth == 12)
{
return 31;
}
else if(nMonth == 4 || nMonth == 6 || nMonth == 9 || nMonth == 11)
{
return 30;
}
else
{
if(nYear%4 == 0)
{
return 28;
}
else
{
return 29;
}
}
}
int WeekType(int year,int month,int day)
{
if(month == 1 || month == 2)
{
month += 12;
--year;
}
int week = -1;
week = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 -year / 100 +year / 400) % 7 + 1;
return week; // 输出-1为错误
}//输出 周一至周日 对应 1-7
以上为本人关于制作日历控件时遇到的逻辑问题 ,当然 日期的显示 按钮切换年月时,显示问题 也遇到很多 ,那就不在本篇博文的范畴之内了 ,如果有人对本人日历控件有兴趣,可私信我发送给你,就不要积分下载了
进步源于分享,下期见~~~ |