计算下一秒的时间

 

题目描述:
计算当前时间的 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] */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值