计算下一秒的时间
题目描述:
计算当前时间的
1
秒后时间,并输出。
如输入当前时间
2006
年
12
月
20
日
19
时
17
分
59
秒
,计算后输出时间是
2006
年
12
月
20
日
19
时
18
分
00
秒
。
程序要求:
程序应该可以运行。通过控制台输入数据,输出数据通过
printf
给出;
1
、实现思路(
3
种)
(
1
)
if-else
(
2
)库函数
(
3
)表驱动
2
、库函数
struct tm {
int tm_sec; /* seconds after the minute - [0,59] */
int tm_min; /* minutes after the hour - [0,59] */
int tm_hour; /* hours since midnight - [0,23] */
int tm_mday; /* day of the month - [1,31]
*/
int tm_mon; /* months since January - [0,11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday - [0,6] */
int tm_yday; /* days since January 1 - [0,365] */
int tm_isdst; /* daylight savings(
夏令时) time flag */
};
(1)把输入转化成内部时间存储:根据输入对结构体依次赋值
(2)加一:转换成 time_t: 用函数time_t __cdecl mktime(struct tm *)实现,加一。
struct tm * __cdecl gmtime(const time_t *);
(3)输出:asctime();
char * __cdecl asctime(const struct tm *);
char * __cdecl ctime(const time_t *);
/* get the time of next sec */
struct tm * nextSec
( struct tm
* ptm
)
{
time_t
t
= mktime
( ptm
); //
t
+= 1;
ptm
= localtime
( &t
);
return
ptm
;
}
3
、表驱动
(
1
)月份天数查表
Month[2][12] (Month[2][13] )
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
0
|
31
|
28
|
31
|
30
|
31
|
30
|
31
|
31
|
30
|
31
|
30
|
31
|
1
|
31
|
29
|
31
|
30
|
31
|
30
|
31
|
31
|
30
|
31
|
30
|
31
|
判断闰年
int isLeapYear( int iYear )
{
return !(iYear % 4 )&&(iYear %100 )|| !( iYear %400 );
}
void NextSec_0( struct tm * ptm )
{
int c1 = 0;
int c2 = 0;
int isLeap;
int mon;
//
秒
c1 = (ptm->tm_sec +1) / 60;
ptm->tm_sec = (ptm->tm_sec +1)% 60;
//
分
c2 = (ptm->tm_min +1)/ 60;
ptm->tm_min = (ptm->tm_min + c1)% 60;
c1 = c2;
//
时
c2 = (ptm->tm_hour +1)/ 24;
ptm->tm_hour = (ptm->tm_hour + c1) % 24;
c1 = c2;
//
日
ptm->tm_mday -= 1; //
调整从
[1~31]
到
[0~30]
isLeap = isLeapYear( ptm->tm_year + 1900 );
mon = ptm->tm_mon;
c2 = (ptm->tm_mday + c1) / Month[isLeap][mon];
ptm->tm_mday = (ptm->tm_mday + c1) % Month[isLeap][mon];
c1 = c2;
ptm->tm_mday += 1;
//
月
c2 = (ptm->tm_mon + c1) / 12;
ptm->tm_mon = (ptm->tm_mon + c1) % 12;
//
年
ptm->tm_year += c2;
}
(2)
进一步查表
创建表:
60
|
60
|
24
|
*
|
12
|
1
|
SEC
|
MIN
|
HOUR
|
DAY
|
MON
|
YEAR
|
说明:第一行为权值,第二行为数位。类似普通加法。
*
:表示不确定
1
:不用进位
void NextSec_1( struct tm * ptm )
{
int i, isLeap, mon;
int c1,
c2;
/*==========
下面建了两个表:第一个类似于普通数的数位
==============*/
/*
*
第一个类似于普通数的数位;
*
第二个类似每位的权值
*/
int *t[NUM] = {
&ptm->tm_sec,
&ptm->tm_min,
&ptm->tm_hour,
&ptm->tm_mday,
&ptm->tm_mon,
&ptm->tm_year
};
int w[NUM] = {
60,
60,
24,
1, /* DAY */
12,
1 /* YEAR */
};
/* ======
表初始化
========= */
w[YEAR] = ptm->tm_year + 1900; //
年份从
1900
年开始
isLeap = isLeapYear(w[YEAR]); //
判断闰年
mon = *t[MON]; //
得到当前月份(
0~11
)
w[DAY] = Month[isLeap][mon]; //
取得当前月份的天数
*t[DAY] -= 1; //
调整
mday
【
1`31
】
[0~30]
/*============
下面是整个计算过程
==============*/
c1 = 1; //
下面的进位
c2 = 0; //
向上的进位
for( i = SEC; i < YEAR; i++ )
{
c2 = (*t[i] + c1 ) / w[i]; //
记录进位
if (c2 == 0)
{
break; // 如果向上没有进位,则计算结束
}
*t[i] = (*t[i] + c1 ) % w[i]; //
计算当前位
c1 = c2;
}
*t[YEAR] += c1; //
将进位加到最高位
*t[DAY] += 1; /*
调整
mday
【
1`31
】
[0~30] */
}