打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
mktime和localtime

2012-08-26 wcdj


由UNIX时间戳转换为系统时间

  1. date -d'1970-01-01 UTC 2147483647 seconds' +"%Y-%m-%d %T %z"             
  2. 2038-01-19 11:14:07 +0800  
  3. date -d'1970-01-01 UTC 2147483648 seconds' +"%Y-%m-%d %T %z"  
  4. date: invalid date "1970-01-01 UTC 2147483648 seconds"  
  5. date -d'1970-01-01 UTC 0 seconds' +"%Y-%m-%d %T"            
  6. 1970-01-01 08:00:00 +0800   

显示当前的UNIX时间戳

  1. date +%s  

Unix时间与系统时间之间的转换
http://shijianchuo.911cha.com/

  1. /*  
  2.  * 2012-08-26 wcdj 
  3.  * 使用Gauss算法解决UNIX时间问题 
  4.  * 将UNIX时间2038-01-19 03:14:08 
  5.  * 支持扩大到2106-02-07 06:28:16 
  6.  */  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <time.h>     // struct tm, mktime  
  10. #include <sys/time.h> // gettimeofday  
  11.   
  12. #define MAX_TIME_DIFF   (24*60*60)  
  13. #define SECS_PER_HOUR   (60 * 60)  
  14. #define SECS_PER_DAY    (SECS_PER_HOUR * 24)  
  15.   
  16.   
  17. // calc microseconds  
  18. long long get_time_of_day()  
  19. {  
  20.     struct timeval tv;  
  21.     if (gettimeofday(&tv, NULL) == 0)   
  22.     {  
  23.         return tv.tv_sec * 1000000ULL + tv.tv_usec;  
  24.     }  
  25.     else   
  26.     {  
  27.         return 0;  
  28.     }  
  29. }  
  30.   
  31.   
  32. static long _timezone = MAX_TIME_DIFF+1;       
  33.   
  34. /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. 
  35.  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 
  36.  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. 
  37.  * 
  38.  * [For the Julian calendar (which was used in Russia before 1917, 
  39.  * Britain & colonies before 1752, anywhere else before 1582, 
  40.  * and is still in use by some communities) leave out the 
  41.  * -year/100+year/400 terms, and add 10.] 
  42.  * 
  43.  * This algorithm was first published by Gauss (I think). 
  44.  * 
  45.  * WARNING: this function will overflow on 2106-02-07 06:28:16 on 
  46.  * machines were long is 32-bit! (However, as time_t is signed, we 
  47.  * will already get problems at other places on 2038-01-19 03:14:08) 
  48.  */  
  49. static inline unsigned int  
  50. my_mktime (unsigned int year, unsigned int mon,  
  51.         unsigned int day, unsigned int hour,  
  52.         unsigned int min, unsigned int sec)  
  53. {  
  54.     if(_timezone == MAX_TIME_DIFF+1)  
  55.     {  
  56.         // 表示_timezone没有初始化  
  57.         struct timeval tv;  
  58.         struct timezone tz;  
  59.         gettimeofday(&tv, &tz);  
  60.         _timezone = tz.tz_minuteswest*60;  
  61.     }  
  62.   
  63.   
  64.     if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */  
  65.         mon += 12;      /* Puts Feb last since it has leap day */  
  66.         year -= 1;  
  67.     }  
  68.   
  69.     /*START 防止"1970-01-01 00:00:00"到"1970-01-01 08:00:00"时间段的错误*/  
  70.   
  71.     unsigned int iRet = (((  
  72.                     (year/4 - year/100 + year/400 + 367*mon/12 + day) +  
  73.                     year*365 - 719499  
  74.                     )*24 + hour /* now have hours */  
  75.                 )*60 + min /* now have minutes */  
  76.             )*60 + sec  /* finally seconds */  
  77.         + _timezone;  /* time_zone */  
  78.   
  79.     if(iRet < 0)  
  80.     {  
  81.         iRet = 0;  
  82.     }  
  83.   
  84.     return iRet;  
  85.   
  86.     /*END*/  
  87. }  
  88.   
  89.   
  90. static long _timezone_ = MAX_TIME_DIFF+1;     
  91. static const unsigned short int __mon_yday[2][13] =  
  92. {  
  93.     /* Normal years.  */  
  94.     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },  
  95.     /* Leap years.  */  
  96.     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }  
  97. };  
  98.   
  99.   
  100. int my_localtime_r(unsigned int *timep, struct tm *result)  
  101. {  
  102.     const unsigned short int *ip;  
  103.     if(_timezone_ == MAX_TIME_DIFF + 1)  
  104.     {  
  105.         struct timeval tv;  
  106.         struct timezone tz;  
  107.         gettimeofday(&tv, &tz);  
  108.         _timezone_ = tz.tz_minuteswest*60;  
  109.     }  
  110.   
  111.     int days = (*timep) / SECS_PER_DAY;  
  112.     unsigned int rem = (*timep) % SECS_PER_DAY;  
  113.     rem -= _timezone_;  
  114.     while (rem < 0)  
  115.     {     
  116.         rem += SECS_PER_DAY;  
  117.         --days;  
  118.     }     
  119.     while (rem >= SECS_PER_DAY)  
  120.     {     
  121.         rem -= SECS_PER_DAY;  
  122.         ++days;  
  123.     }   
  124.   
  125.     result->tm_hour = rem / SECS_PER_HOUR;  
  126.     rem %= SECS_PER_HOUR;  
  127.     result->tm_min = rem / 60;   
  128.     result->tm_sec = rem % 60;   
  129.     /* January 1, 1970 was a Thursday.  */  
  130.     result->tm_wday = (4 + days) % 7;  
  131.     if (result->tm_wday < 0)  
  132.         result->tm_wday += 7;  
  133.   
  134.     int y = 1970;  
  135.   
  136. #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))  
  137. #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))  
  138. #ifndef __isleap  
  139.     /* Nonzero if YEAR is a leap year (every 4 years, 
  140.      *   *    except every 100th isn't, and every 400th is).  */  
  141. # define __isleap(year) \  
  142.     ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))  
  143. #endif  
  144.   
  145.     while (days < 0 || days >= (__isleap (y) ? 366 : 365))  
  146.     {     
  147.         /* Guess a corrected year, assuming 365 days per year.  */  
  148.         long int yg = y + days / 365 - (days % 365 < 0);   
  149.   
  150.         /* Adjust DAYS and Y to match the guessed year.  */  
  151.         days -= ((yg - y) * 365   
  152.                 + LEAPS_THRU_END_OF (yg - 1)  
  153.                 - LEAPS_THRU_END_OF (y - 1));  
  154.         y = yg;   
  155.     }     
  156.     result->tm_year = y - 1900;  
  157.     if (result->tm_year != y - 1900)  
  158.     {     
  159.         /* The year cannot be represented due to overflow.  */  
  160.         return -1;  
  161.     }     
  162.     result->tm_yday = days;  
  163.     ip = __mon_yday[__isleap(y)];  
  164.     for (y = 11; days < (long int) ip[y]; --y)  
  165.         continue;  
  166.     days -= ip[y];  
  167.     result->tm_mon = y;  
  168.     result->tm_mday = days + 1;  
  169.   
  170.     return 0;  
  171. }  
  172.   
  173.   
  174.   
  175. // return readable format time  
  176. size_t get_date_str(time_t tsrc, char *buffer, size_t len)  
  177. {     
  178.     struct tm tm = {0};  
  179.   
  180.     /*  
  181.      * modify  
  182.      */  
  183.     //localtime_r(&tsrc, &tm);// the reentrant version  
  184.     my_localtime_r((unsigned int *)&tsrc, &tm);  
  185.   
  186.   
  187.     int iMicrosec = get_time_of_day() % 1000000;  
  188.   
  189.     return snprintf(buffer, len, "%04d-%02d-%02d %02d:%02d:%02d %d",  
  190.             tm.tm_year + 1900,   
  191.             tm.tm_mon + 1,   
  192.             tm.tm_mday,  
  193.             tm.tm_hour,   
  194.             tm.tm_min,   
  195.             tm.tm_sec,  
  196.             iMicrosec);  
  197. }  
  198.   
  199.   
  200. int main(int argc, char** argv)  
  201. {  
  202.   
  203.     unsigned int now = get_time_of_day()/1000000;  
  204.     printf("unixi timestamp: %u\n", now);// date +%s  
  205.   
  206.     char szTime[128] = {0};       
  207.     get_date_str(now, szTime, sizeof(szTime));  
  208.     printf("current time: [%s]\n", szTime);  
  209.   
  210.   
  211. #if 1  
  212.     /* test for localtime_r*/  
  213.   
  214.     // [1]  
  215.     now = 0;  
  216.     memset(szTime, 0x0, sizeof(szTime));  
  217.     get_date_str(now, szTime, sizeof(szTime));  
  218.     printf("time: [%s]\n", szTime);  
  219.   
  220.     // [2]  
  221.     now = 4294967295U;// max of unsigned int  
  222.     memset(szTime, 0x0, sizeof(szTime));  
  223.     get_date_str(now, szTime, sizeof(szTime));  
  224.     printf("time: [%s]\n", szTime);  
  225.   
  226.     // [3]  
  227.     now = 2147483647;// max of int  
  228.     memset(szTime, 0x0, sizeof(szTime));  
  229.     get_date_str(now, szTime, sizeof(szTime));  
  230.     printf("time: [%s]\n", szTime);  
  231.   
  232.   
  233. #endif  
  234.   
  235.   
  236.     /* test for mktime */  
  237.     time_t rawtime;  
  238.     struct tm * timeinfo;  
  239.     int year, month, day;  
  240.     // prompt user for date  
  241.     printf("Enter year: ");scanf("%d", &year);  
  242.     printf("Enter month: ");scanf("%d", &month);  
  243.     printf("Enter day: ");scanf("%d", &day);  
  244.   
  245.     // get current timeinfo and modify it to the user's choice  
  246.     time(&rawtime);  
  247.     timeinfo = localtime(&rawtime);  
  248.     timeinfo->tm_year = year - 1900;  
  249.     timeinfo->tm_mon = month -1;  
  250.     timeinfo->tm_mday = day;  
  251.   
  252.     unsigned int rettime;   
  253.     /*if (-1 != (rettime = mktime(timeinfo))) 
  254.     { 
  255.         printf("mktime ret: %d\n", rettime); 
  256.     } 
  257.     else 
  258.     { 
  259.         printf("mktime err!\n"); 
  260.     }*/  
  261.   
  262.     if(timeinfo->tm_year + 1900 > 2106  
  263.             || (timeinfo->tm_year + 1900 == 2106 && timeinfo->tm_mon + 1 > 2)  
  264.             || (timeinfo->tm_year + 1900 == 2106 && timeinfo->tm_mon + 1 == 2 && timeinfo->tm_mday > 6))  
  265.     {  
  266.         printf("Error, overflow 4294967295!\n");  
  267.     }  
  268.     else  
  269.     {  
  270.         rettime = my_mktime(year, month, day, 0, 0, 0);  
  271.         printf("mktime ret: %u\n", rettime);  
  272.     }  
  273.   
  274.   
  275.   
  276.     return 0;  
  277. }  
  278. /* 
  279. output: 
  280.  
  281. unixi timestamp: 1345548878 
  282. current time: [2012-08-21 19:34:38 737638] 
  283. time: [1970-01-01 08:00:00 737648] 
  284. time: [2106-02-07 14:28:15 737652] 
  285. time: [2038-01-19 11:14:07 737655] 
  286.  
  287.  
  288. */  

参考

[1]  Linux源码中的mktime算法解析(关于Gauss算法的解释)



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
c语言中时间的获取
Linux常用C函数-日期时间篇 -
(一)linux下的定时或计时操作(gettimeofday等的用法,秒,微妙,纳秒)_鲍...
Linux C函数之时间函数
Linux获取精确日历函数
PHP FFI 允许在 PHP 脚本中嵌入原始 C 代码
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服