自己用c语言做的日历

时间:2022-03-08 09:17:55

日历用了能变颜色的功能,突出显示当前日期,但是因为用了个死循环,又是单线程的,所以如果要显示当前系统时间(精确到秒)的话,执行此操作就不能继续下去了



#include<iostream>

#include<iomanip>
#include <windows.h>
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;


//改变颜色的函数
/*颜色对应值:
   0=黑色                8=灰色  
     1=蓝色                9=淡蓝色
   2=绿色                10=淡绿色       0xa
   3=湖蓝色            11=淡浅绿色        0xb 
   4=红色                12=淡红色        0xc
   5=紫色                13=淡紫色        0xd
   6=黄色                14=淡黄色        0xe
   7=白色                15=亮白色        0xf
   也可以把这些值设置成常量。
 */
void color(const unsigned short color1)
{
    /*仅限改变0-15的颜色;如果在0-15那么实现它的颜色   因为如果超过15后面的改变的是文本背景色。*/
    if(color1>=0&&color1<=15)
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color1);
    /*如果不在0-15的范围颜色,那么改为默认的颜色白色;*/
    else
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}


bool leapyear(int year) //判断是否为闰年
{
    if(year%4==0&&year%100!=0||year%400==0)
        return true;
    else
        return false;
}


/*输出整个日历*/
void _calendar(int year,int _year,int month,int _month,int day,int _day)  //year,month,day为当前系统日期,加下划线为正在查看的日期
{
    int days=0,i,j;   //year是当年年份,month是当前月份,days是自1970年到当前月份的天数

    for(i=1970; i<_year; i++) //得到自1970年到当前年份的天数
    {
        if(leapyear(i))
            days+=366;
        else
            days+=365;
    }


    int yuefen[12]= {31,28,31,30,31,30,31,31,30,31,30,31};  //每个月的天数
    if(leapyear(_year))       //如果是闰年,2月是29天
        yuefen[1]=29;
    for(j=0; j<_month-1; j++)
    {
        days+=yuefen[j];           //得到这年到当前月份的天数
    }
    days%=7;
    int startwk=(days+4)%7;  //因为1970年1月1日是星期四,所以如果days等于0就是星期四

    color(10);            //淡绿色
    printf("                当前年份:%d ,当前查看的月份为:%d\n",_year,_month);           //于程序开头显示当前显示的日历的年月
    color(16);

    int numdays=yuefen[_month-1];  //这个月有几天
    i=0;
    int count=0;   //count是用来控制输出星期的格式的
    printf("                     "); //为了使日历在屏幕上居中

    printf(" 日 一 二 三 四 五 六 \n");

    printf("                     ");                //为了使日历在屏幕上居中
    for(; i<startwk; i++) //格式化输出星期的位置
    {

        printf("   ");
        count++;
    }
    for(i=1; i<=numdays; i++) //按顺序输出日期
    {
        if(_year==year&&day==_day&&month==_month)    //如果是当前系统日期则变颜色
        {
            if(i==day)
            {

                color(14);
                printf("%3d",i);
                color(16);
            }
            else
                printf("%3d",i);
        }
        else
            printf("%3d",i);
        count++;
        if(count%7==0)       //换行
        {
            printf("\n");
            printf("                     ");    //为了使日历在屏幕上居中
        }
    }
    printf("\n\n");


}






void calendar(int year,int month,int day)   //startwk是这个月第一天星期几,0是星期天,6是星期六,numdays是这个月的总天数
{

    int _year=year,_month=month,_day=day,i;
    _calendar(year,_year,month,_month,day,_day);  //程序一运行即输出系统日期
    for(;;)                                     //无限制查看上个月或下个月的日期,直到想看当前实时时间进入死循环就没办法操作了
    {
        color(11);
        printf("      如果想查看现在的时间,请输入0(请注意,使用本功能后程序将无法再进行操作)\n");
        printf("      看上个月日历请按1,看下个月日历请按2\n      请输入:");
        color(16);
        scanf("%d",&i);
        if(i==0)
            break;
        if(i==1)         //如果跨年则要考虑“进位”,看上个月日历
        {
            if(_month==1)
            {
                _month=12;
                _year-=1;
            }
            else
                _month--;
            system("cls");                         //清屏
            _calendar(year,_year,month,_month,day,_day);
        }
        if(i==2)        //看下个月日历
        {
            if(_month==12)
            {
                _month=1;
                _year+=1;
            }
            else
                _month++;
            system("cls");
            _calendar(year,_year,month,_month,day,_day);
        }
    }



}

void rili()  //只能从1970年到以后的才成立,用来读取系统时间并调用输出日历的函数
{
    int year,month,day,which_month;
    time_t curtime=(time_t) 0;
    time(&curtime);
    struct tm*reatime=NULL;
    reatime=localtime(&curtime);
    year=reatime->tm_year+1900;
    month=reatime->tm_mon+1;
    day=reatime->tm_mday;

    calendar(year,month,day);

}










//取系统时间并输出日历
void systime()
{

    int t=0;          //用来使输出星期几的时候用中文代替阿拉伯数字
    time_t curtime=(time_t) 0;
    struct tm*reatime=NULL;


    rili();        //在进入死循环前先进行其他操作,即输出当前日历和查看上月、下月日历






    while(1)                //用来输出实时时间的死循环,暂时不知道该怎么跳出来。。所以一旦该程序运行就无法进行其他任何操作
    {
        time(&curtime);
        reatime=localtime(&curtime);
        printf("\r%04d年%02d月%2d日 星期"
               ,reatime->tm_year+1900
               ,reatime->tm_mon+1
               ,reatime->tm_mday
              );

        t=reatime->tm_wday;
        switch(t)
        {

        case 1:
            printf("一 ");
            break;
        case 2:
            printf("二 ");
            break;
        case 3:
            printf("三 ");
            break;
        case 4:
            printf("四 ");
            break;
        case 5:
            printf("五 ");
            break;
        case 6:
            printf("六 ");
            break;
        case 7:
            printf("七 ");
            break;
        }

        printf("时间:%02d:%02d:%02d"
               ,reatime->tm_hour
               ,reatime->tm_min
               ,reatime->tm_sec);

        Sleep(100);            //停100毫秒,以免程序一直死循环会对电脑cpu占用过多
    }

}




int main()  //程序开始运行的地方。。虽然把systime()函数全部挪到这里完全可以。。不过看起来更清爽
{
    color(12);
    printf("                             WELCOME!! \n");
    color(16);
    systime();
    return 0;
 
}