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