制作日历,其中一些逻辑上的代码 难点 (记录)

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 09:08   11   0

前端时间,公司需要一个日历控件,在网上看了很多 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

以上为本人关于制作日历控件时遇到的逻辑问题 ,当然 日期的显示 按钮切换年月时,显示问题 也遇到很多 ,那就不在本篇博文的范畴之内了 ,如果有人对本人日历控件有兴趣,可私信我发送给你,就不要积分下载了

进步源于分享,下期见~~~

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP