C/C++ 中的时间和日期

今天的任务是把日期(年月日时分秒)转换为秒(自1970年开始)

首先介绍struct tm  time_t

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 */
};
#ifdef _USE_32BIT_TIME_T
typedef __time32_t time_t;      /* time value */
#else
typedef __time64_t time_t;      /* time value */
#endif

time_t用于表示秒数(自1970.01.01.00:00:00)  其中32位的time_t可以表示的时间范围是[1970.01.01.00:00:00, 2038.01.18.19:14:07], 64位的time_t可以表示范围为:[1970.01.01.00:00:00, 3001.01.01.00:00:00)

tm用于表示日期

采用函数time_t mktime(struct tm *_Tm) 可以实现日期转换为秒。

采用函数time_t time(time_t *timer)可以获取当前系统时间相对与1970年1月1日已经走过的秒数

struct tm * gmtime(const time_t *timer);  把秒数转换为以格林威治时间为标准的日期。

struct tm * localtime(const time_t * timer); 把秒数转换为当地时间为标准的日期。

输出时间和日期:

char * asctime(const struct tm * timeptr);  

char * ctime(const time_t *timer);

两者均以相同的格式输出: 星期 月份 日期 时:分:秒 年\n\0   例如:

Wed Jan 02 02:03:55 1980\n\0

 其实asctime函数只是很简单地提取tm中的参数

而ctime则需要先把时间转换为本地时间为标准的日期,然后再调用asctime函数

ctime(&t) 相当于:

tm TM = localtime(&t);

ctime(&TM);

例子:

#include <stdio.h>
#include <time.h>
int main()
{
    time_t t = time(NULL);
    printf("the seconds since 1970 : %I64d\n", t); 
    tm *TM;
    TM = localtime(&t);
    printf("the date today is : %s",asctime(TM));
    printf("the date today is : %s",ctime(&t));
    return 0;
}

 

localtime和gmtime,不是线程安全的,我们可以用localtime_r和gmtime_r代替

struct tm* localtime_r( const time_t* timer, struct tm* result );

 

如果想自己实现时间与日期的转换,可以参考下Linux内核下的mktime()函数

unsigned long  
mktime(const unsigned int year0, const unsigned int mon0,  
       const unsigned int day, const unsigned int hour,  
       const unsigned int min, const unsigned int sec)  
{  
    unsigned int mon = mon0, year = year0;  
  
    /* 1..12 -> 11,12,1..10 */  
    if (0 >= (int) (mon -= 2)) {  
        mon += 12;  /* Puts Feb last since it has leap day */  
        year -= 1;  
    }  
  
    return ((((unsigned long)  
          (year/4 - year/100 + year/400 + 367*mon/12 + day) +  
          year*365 - 719499  
        )*24 + hour /* now have hours */  
      )*60 + min /* now have minutes */  
    )*60 + sec; /* finally seconds */  
}  

以下是介绍这个算法的一篇文章。。表示没看懂。自己试过以后,好像也不太准,莫非打开方式不正确?求强大的程序猿解答>.<

http://www.linuxidc.com/Linux/2011-08/41854.htm

 

 

 

 

 

posted on 2014-04-14 20:32  Elenno  阅读(594)  评论(0编辑  收藏  举报

导航