LINUX C系统编程与PYTHON中的时间模块对比

今天看python时间模块time的时候发现和LINUX系统编程中的时间调用函数基本一样,以前刚好没有好好学习LINUX C编程的时间模块就对比进行了学习。

  • 本文只是给出函数接口和使用方式,详细了解请参考LINUX main page和PYTHON help
  • 本文不涉及asctime和ctime,并且C中涉及多线程编程注意选择可重入性函数

一、时间存在方式

其实不管是C还是PYTHON这里都包含3种时间不同存在的方式

  • 日历时间:Epoch以来的秒及新纪元时间(1970年1月1日 00:00:00)以来的秒
  • 分解时间:实际上是时间在程序内部存在的结构,也是一个中间介质,C中使用结构体,PYTHON中使用元组
  1. LINUX C为tm结构体:
struct tm {
              int tm_sec;         /* seconds */
              int tm_min;         /* minutes */
              int tm_hour;        /* hours */
              int tm_mday;        /* day of the month */
              int tm_mon;         /* month */
              int tm_year;        /* year */
              int tm_wday;        /* day of the week */
              int tm_yday;        /* day in the year */
              int tm_isdst;       /* daylight saving time */
                                  /* >0 DST is in effect
                                     =0 DST is not effect;
                                     <0 DST information not available
                                   */         
          };
  1. PYTHON struct_time元组:
索引(Index)   属性(Attribute)   
0               tm_year(年)     
1               tm_mon(月)    
2               tm_mday(日)  
3               tm_hour(时)  
4               tm_min(分)    
5               tm_sec(秒)   
6               tm_wday(weekday)     
7               tm_yday(一年中的第几天)    
8               tm_isdst(是否是夏令时)     

可以看到他们基本是一致的

  • 可读时间:这种一般就是我们平时看到的一些方便读取的的时间,比如
2017-10-12 06:52:03(AM) +0800

就是方便人类读取的可读取时间

LINUX C可读时间格式:

%a     The abbreviated weekday name according to the current locale.
%A     The full weekday name according to the current locale.
%b     The abbreviated month name according to the current locale.
%B     The full month name according to the current locale.
%c     The preferred date and time representation for the current locale.
%C     The century number (year/100) as a 2-digit integer. (SU)
%d     The day of the month as a decimal number (range 01 to 31).
%D     Equivalent  to  %m/%d/%y.   (Yecch—for  Americans only.  Americans should note that in other countries %d/%m/%y is rather common.  This means that in
      international context this format is ambiguous and should not be used.) (SU)
%e     Like %d, the day of the month as a decimal number, but a leading zero is replaced by a space. (SU)
%E     Modifier: use alternative format, see below. (SU)
%F     Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)
%G     The ISO 8601 week-based year (see NOTES) with century as a decimal number.  The 4-digit year corresponding to the ISO week number (see %V).  This has
      the same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead. (TZ)
%g     Like %G, but without century, that is, with a 2-digit year (00-99). (TZ)
%h     Equivalent to %b.  (SU)
%H     The hour as a decimal number using a 24-hour clock (range 00 to 23).
%I     The hour as a decimal number using a 12-hour clock (range 01 to 12).
%j     The day of the year as a decimal number (range 001 to 366).
%k     The hour (24-hour clock) as a decimal number (range 0 to 23); single digits are preceded by a blank.  (See also %H.)  (TZ)
%l     The hour (12-hour clock) as a decimal number (range 1 to 12); single digits are preceded by a blank.  (See also %I.)  (TZ)
%m     The month as a decimal number (range 01 to 12).
%M     The minute as a decimal number (range 00 to 59).
%n     A newline character. (SU)
%O     Modifier: use alternative format, see below. (SU)
%p     Either  "AM" or "PM" according to the given time value, or the corresponding strings for the current locale.  Noon is treated as "PM" and midnight as
      "AM".
%P     Like %p but in lowercase: "am" or "pm" or a corresponding string for the current locale. (GNU)
%r     The time in a.m. or p.m. notation.  In the POSIX locale this is equivalent to %I:%M:%S %p.  (SU)
%R     The time in 24-hour notation (%H:%M).  (SU) For a version including the seconds, see %T below.
%s     The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). (TZ)
%S     The second as a decimal number (range 00 to 60).  (The range is up to 60 to allow for occasional leap seconds.)
%t     A tab character. (SU)
%T     The time in 24-hour notation (%H:%M:%S).  (SU)
%u     The day of the week as a decimal, range 1 to 7, Monday being 1.  See also %w.  (SU)
%U     The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01.  See also %V and
      %W.
%V     The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days
      in the new year.  See also %U and %W.  (SU)
%w     The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.
%W     The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01.
%x     The preferred date representation for the current locale without the time.
%X     The preferred time representation for the current locale without the date.
%y     The year as a decimal number without a century (range 00 to 99).
%Y     The year as a decimal number including the century.
%z     The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)
%Z     The timezone name or abbreviation.
%+     The date and time in date(1) format. (TZ) (Not supported in glibc2.)
%%     A literal '%' character.

python 可读时间格式:

%Y  Year with century as a decimal number.
%m  Month as a decimal number [01,12].
%d  Day of the month as a decimal number [01,31].
%H  Hour (24-hour clock) as a decimal number [00,23].
%M  Minute as a decimal number [00,59].
%S  Second as a decimal number [00,61].
%z  Time zone offset from UTC.
%a  Locale's abbreviated weekday name.
%A  Locale's full weekday name.
%b  Locale's abbreviated month name.
%B  Locale's full month name.
%c  Locale's appropriate date and time representation.
%I  Hour (12-hour clock) as a decimal number [01,12].
%p  Locale's equivalent of either AM or PM.

Other codes may be available on your platform.  See documentation for
the C library strftime function.

本文使用这三个术语

二、日历时间

下面方法获取当前系统时间的当前时间

  • LINUX C:
    int gettimeofday(struct timeval *tv,struct timezone *tz);
    time_t time(time_t *timep)
  • PYTHON:
    time.time()
    上面的方式都是获取当前时间的日历时间的方式为了方便我们使用time方法

三、日历时间转换为分解时间

  • LINUX C:
    strcut tm* gmtime(const time_t* timep);
    strcut tm* localtime(const time_t* timep);
Each of these functions returns the value described, or NULL  in case an error was detected.
  • PYTHON:
    time.gmtime(seconds=None)
    time.localtime(seconds=None)

可以看到他们是一致的其中gmtime代表返回UTC时间,而localtime代表返回本地时区时间

四、将分解时间转换为日历时间

  • LINUX C:
    time_t mktime(struct tm* tmieptr)
RETURN VALUE
      -1 in case of mktime() in case an error was detected.
  • PYTHON:
    time.mktime(p_tuple)

五、将分解时间转换为可读时间

  • LINUX C:
    size_t strftime(char *s, size_t max, const char *format,const struct tm *tm);
RETURN VALUE
      Provided that the result string, including the terminating null byte, does not exceed max bytes, strftime() returns the number of bytes (excluding the ter‐
      minating  null  byte)  placed  in the array s.  If the length of the result string (including the terminating null byte) would exceed max bytes, then strf‐
      time() returns 0, and the contents of the array are undefined.  (This behavior applies since at least libc 4.4.4; very old versions of libc, such  as  libc
      4.4.1, would return max if the array was too small.)

      Note  that the return value 0 does not necessarily indicate an error.  For example, in many locales %p yields an empty string.  An empty format string will
      likewise yield an empty string.
  • PYTHON:
    strftime(format, p_tuple=None)

这里需要注意format,format在文章开头已经给出

六、将可读时间转换为分解时间

  • LINUX C:
    char *strptime(const char *s, const char *format, struct tm *tm);
RETURN VALUE
      The return value of the function is a pointer to the first character not processed in this function call.  In case the input string contains  more  charac‐
      ters  than required by the format string the return value points right after the last consumed input character.  In case the whole input string is consumed
      the return value points to the null byte at the end of the string.  If strptime() fails to match all of the format string and therefore an  error  occurred
      the function returns NULL.
  • PYTHON:
    strptime(string, format)
    这里需要注意format,format在文章开头已经给出

七、转换图

这里给出一张LINUX系统编程手册里面的一张图,其实python是一样的,红色箭头是本文涉及的函数

Paste_Image.png

八、方法使用举例

下面使用C和PYTHON分别实现将日期

2017-10-12 08:52:03(AM) CST

转换分解时间,日历时间然后再减去3600秒转换回分解时间和可读时间的小程序,以熟悉使用方式

  • C程序:
/*************************************************************************
 > File Name: testtime.c
 > Author: gaopeng QQ:22389860 all right reserved
 > Mail: gaopp_200217@163.com
 > Created Time: Wed 01 Nov 2017 02:28:25 AM CST
************************************************************************/

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define MAXSIZE 99


int  rtime2ctime(/*in*/const char* r_time,/*out*/time_t* ctime)
{
       time_t i_ctime;
       struct tm tm_st;
       //此处根据固定测试转换为分解时间tm_st
       if ( !strptime(r_time,"%Y-%m-%d %X(%p) %z",&tm_st))
       {
               return -1;
       }

       //此处将分解时间tm_st转换为日历时间ctime
       if( (*ctime = mktime(&tm_st)) == -1)
       {
               return -1;
       }

       return 0;
}


int ctime2rtime(/*in*/time_t c_time)
{

       struct tm* tm_st = NULL;
       char time[MAXSIZE] ;
       //此处将日历时间转换为分解时间
       if((tm_st = localtime(&c_time)) == NULL)
       {
               return -1;
       }


       //此处将分解时间转换为可读时间
       if(strftime(time,MAXSIZE-1,"%Y-%m-%d %X(%p) %z",tm_st) == 0)
       {
               return -1;
       }

       printf("%s\n",time);
       return 0;
}



int main(void)
{
       char r_time[100] = "2017-10-12 07:52:03(AM) +0800";
       time_t ctime;

       if( rtime2ctime(r_time,&ctime) == -1 )
       {
               printf("rtime2ctime error\n");
               return -1;
       }

       printf("2017-10-12 07:52:03(AM) +0800 to calenlar time is:%ld\n",ctime);

       ctime = ctime - (time_t)3600;


       printf("after sub 1 hours time is:");

       if(ctime2rtime(ctime) == -1)
       {
               printf("ctime2rtime error\n");
       }

}
  • python程序:
import time

def rtime2ctime(r_time):
    #此处根据固定测试可读时间转换为分解时间
    p_time = time.strptime(r_time,"%Y-%m-%d %X(%p) %z")
    #此处将分解时间tm_st转换为日历时间
    return time.mktime(p_time)

def ctime2rtime(ctime):
    #此处将日历时间转换为分解时间
    p_time = time.localtime(ctime)
    #此处将分解时间转换为可读时间
    r_time = time.strftime("%Y-%m-%d %X(%p) %z",p_time)
    return r_time

r_time="2017-10-12 06:52:03(AM) +0800"
ctime = rtime2ctime(r_time)
print("2017-10-12 06:52:03(AM) +0800 to calenlar time is:%d" %(ctime))
ctime = ctime - 3600
print("after sub 1 hours time is:%s" %(ctime2rtime(ctime)))

他们的运行结果均是:

2017-10-12 06:52:03(AM) +0800 to calenlar time is:1507762323
after sub 1 hours time is:2017-10-12 05:52:03(AM) +0800

作者微信:

微信.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容