linux c时间

2018-05-21 19:59:56

日历时间

#include <sys/time.h>

struct timeval{
    time_t tv_sec;        /*自1970-01-01 00:00:00到现在的秒数*/
    suseconds_t tv_usec;	/*额外的微妙数*/
};

int gettimeofday(struct timeval *tv, struct timezone *tz);
//成功返回0,失败返回-1

tz已废弃,实际调用的时候置为NULL就行。

#include <time.h>

time_t time(time_t *timep);
//返回秒数,失败返回-1

如果timep不为NULL,则秒数还会存入timep。有这个time系统调用因为历史的原因,现在一般用gettimeofday()即可。


时间戳转成分解时间

#include <time.h>

struct tm{
  int tm_sec;			/* Seconds.	[0-60] (1 leap second) */
  int tm_min;			/* Minutes.	[0-59] */
  int tm_hour;			/* Hours.	[0-23] */
  int tm_mday;			/* Day.		[1-31] */
  int tm_mon;			/* Month.	[0-11] */
  int tm_year;			/* Year	- 1900.  */
  int tm_wday;			/* Day of week.	[0-6] */
  int tm_yday;			/* Days in year.[0-365]	*/
  int tm_isdst;			/* DST.		[-1/0/1]*/
}

struct tm *gmtime(const time_t *timep);     //标准时间
struct tm *localtime(const time_t *timep);  //本地时间

//成功返回静态分配的内存的指针,错误返回NULL


本地时区的分解时间转成时间戳

#include <time.h>

time_t mktime(struct tm *timeptr);
//错误返回-1

将分解时间转成打印格式

#include <time.h>

size_t strftime(char *outstr, size_t maxsize, const char *format, const struct tm *timeptr);
//返回多少字节存入outstr(不包括\0),出错返回0

将打印格式转成分解时间

#define _XOPEN_SOURCE
#include <time.h>

char *strptime(const char *str, const char *format, struct tm *timeptr);


例子

#include <stdio.h>
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdint.h>


int main(void){
    //获取datetime
    char buf[64];
    struct tm *tm1;
    time_t secs;
    
    secs = time(NULL);
    tm1 = localtime(&secs);
    strftime(buf, 64, "%Y-%m-%d %H:%M:%S", tm1);
    printf("%s\n", buf);
    
    //返回毫秒总数
    struct timeval tv;
    uintptr_t msec;

    gettimeofday(&tv, NULL);
    msec = tv.tv_sec*1000 + tv.tv_usec/1000;
    printf("%lu\n\n", msec);
    
    //获取一个月前,2小时前的datetime和时间戳
    tm1->tm_mon -= 1;
    tm1->tm_hour -= 2;
    strftime(buf, 64, "%Y-%m-%d %H:%M:%S", tm1);
    printf("%s\n", buf);
    
    secs = mktime(tm1);
    printf("%ld\n\n", secs);
    
    //datetime转成时间戳
    struct tm tm2;
    if(strptime(buf, "%Y-%m-%d %H:%M:%S", &tm2) == NULL) perror("strptime");
    secs = mktime(&tm2);
    printf("%ld\n", secs);
     
}
/*
2018-05-21 20:08:32
1526904512598

2018-04-21 18:08:32
1524305312

1524305312
*/



时区

linux系统本地时区由/etc/localtime定义,通常链接到/usr/share/zoneinfo下的一个文件

ll /etc/localtime 
lrwxrwxrwx 1 root root 33 Oct 15  2017 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai

想要在特定时区运行程序,可以设置环境变量TZ如

TZ=":Asia/Shanghai"
./a.out


地区(Locale)

世界各地在使用数千种语言,其中在计算机系统上经常使用的占了相当比例。此外,在显示诸如数字、货币、日期和时间之类的信息时,不同国家的习俗也不同。例如,大多数欧洲国家使用逗号,而非小数点来分割实数的整数和小数部分。想要在多个地理区位运行程序都应处理locale来满足不同的语言和格式来显示用户的输入显示信息,是个相当复杂的课题。

cat /etc/locale.conf
#LANG=en_US.UTF-8

#常看当前的locale
locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

#查看系统所有的locale
locale -a

#部分显示如下
yi_US
yi_US.cp1255
yi_US.utf8
yo_NG
yo_NG.utf8
yue_HK
yue_HK.utf8
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
#include <locale.h>

char *setlocale(int category, const char *locale);
//失败返回NULL,成功返回字符串(静态分配的内存)指针

LC_ALL代表上图的全部。

setlocale(LC_ALL, "");
//从环境变量获取locale
#include <stdio.h>
#include <locale.h>
#include <time.h>

int main(){
    char *lc = setlocale(LC_ALL, "zh_CN.utf8");
    printf("%s\n", lc);
}
/*
zh_CN.utf8
*/


更新系统时间

这些函数很少会用到,一般系统时间用工具设置一次就够了。在这里这是简单列出

#define _BSD_SOURCE
#include <sys/time.h>

int settimeofday(const struct timeval *tv, const struct timezone *tz);
//成功返回0,失败返回-1

和gettimeofday()一样,tz参数废弃。这个函数会把时间突然改变。可能会影响到一些依赖于系统时钟单调递增的应用。所以几秒钟的小差距应该用adjtime来调整。

int adjtime(struct timeval *delta, struct timeval *olddelta);

这个函数会根据delta的正负慢慢的调整时钟。


进程时间

cpu时间分为2部分

1.用户cpu时间-在用户模式下执行所花费的时间
2.系统cpu时间-在内核模式下所花费的时间,一般为系统调用所花费的时间。

shell里可用time命令获取一个程序花费的cpu时间。

time ./a.out

real	0m0.001s
user	0m0.000s
sys	0m0.001s
#include <sys/times.h>
#include <time.h>

//返回的计时单位不是秒,而是时钟计时单元
//错误返回-1
clock_t times(struct tms *buf);

//获取总的cpu时间(包括用户和系统)
//返回的计量单位是CLOCKS_PER_SEC
//错误返回-1
clock_t clock(void);

//程序执行到此刻的cpu时间
struct tms {
    clock_t tms_utime; /* User CPU time used by caller */
    clock_t tms_stime; /* System CPU time used by caller */
    clock_t tms_cutime; /* User CPU time of all (waited for) children */
    clock_t tms_cstime; /* System CPU time of all (waited for) children */
};

例子

#include <stdio.h>
#include <sys/times.h>
#include <time.h>
#include <unistd.h>


int main(void){
    struct tms t;
    int i;
    printf("CLOCKS_PER_SEC=%ld  sysconf(_SC_CLK_TCK)=%ld\n\n",
            CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK));
    
    clock_t clockTime = clock();
    if (clockTime == -1) perror("clock");
    printf("clock() returns: %ld clocks-per-sec (%.2f secs)\n",clockTime, (double) clockTime / CLOCKS_PER_SEC);

    if (times(&t) == -1) perror("times");
    printf("user CPU=%.2f; system CPU: %.2f\n\n",
            (double) t.tms_utime / sysconf(_SC_CLK_TCK),
            (double) t.tms_stime / sysconf(_SC_CLK_TCK));
    
    
    for(i=0; i < 100000000; i++){
        getppid();
    }
    
    
    clockTime = clock();
    if (clockTime == -1) perror("clock");
    printf("clock() returns: %ld clocks-per-sec (%.2f secs)\n",clockTime, (double) clockTime / CLOCKS_PER_SEC);

    if (times(&t) == -1) perror("times");
    printf("user CPU=%.2f; system CPU: %.2f\n",
            (double) t.tms_utime / sysconf(_SC_CLK_TCK),
            (double) t.tms_stime / sysconf(_SC_CLK_TCK));
   
}

/*
CLOCKS_PER_SEC=1000000  sysconf(_SC_CLK_TCK)=100

clock() returns: 0 clocks-per-sec (0.00 secs)
user CPU=0.00; system CPU: 0.00

clock() returns: 8330000 clocks-per-sec (8.33 secs)
user CPU=2.36; system CPU: 5.97
*/


总结

本文对linux c时间做了简单的介绍,如果有疑问可以给我留言。


备注

1.编译器版本gcc4.8,运行环境centos7 64位
2.原文地址http://www.freecls.com/a/2712/2f

©著作权归作者所有
收藏
推荐阅读
  • linux进程凭证(权限)

    每个进程都有一套用数字表示的用户id和组id,这些id决定了进程执行时具体的权限。实际用户id和实际组id这2个id决定了进程所属的用户和组。假设我们用root用户登录,那么我们在shell中创建的新...

  • linux用户和组

    linux上每个用户都拥有一个唯一的用户名和一个相对应的用户id(uid),用户可以隶属于一个或多个组。每个组也拥有一个唯一的组名和组id(gid)。用户和组主要是用来控制资源访问权限的。记录用户相关...

  • err
    linux动态内存分配

    进程可以通过增加堆的大小来分配内存,堆就是一段长度可变的连续的虚拟内存,开始于未初始化数据段末尾,随着内存的分配和释放增减。通常堆的当前内存边界称为program bre...

  • err
    linux进程

    进程是一个可执行程序的实例。程序包含了一系列信息,这些信息描述了如何在运行时创建一个进程,所包含的内容如下。1.二进制格式标识,linux上用的是elf格式2.机器语言指...

  • err
    linux文件io(open、read、write、close)

    所有执行io操作的系统调用都是以文件描述符(大于0的整数)来指代打开的文件。文件描述符可以表示诸如管道(pipe)、fifo、socket、终端、设备和普通文件。对于每个...

  • nginx模块 ngx_http_headers_module

    ngx_http_headers_module 模块是用来增加 Expires 和 Cache-control,或者是任意的响应头。Syntax: add_header name value [alw...

  • nginx模块 ngx_http_gunzip_module、ngx_http_gzip_module、ngx_http_gzip_static_module

    ngx_http_gunzip_module 模块将文件解压缩后并在响应头加上 "Content-Encoding: gzip" 返回给客户端。为了解决客户端不支持gzip压缩。编译的时候带上 --w...

  • nginx模块 ngx_http_flv_module、ngx_http_mp4_module

    ngx_http_flv_module模块提供了对 flv 视频的伪流支持。编译的时候带上 --with-http_flv_module。它会根据指定的 start 参数来指定跳过多少字节,并在返回数...

  • nginx模块 ngx_http_fastcgi_module

    ngx_http_fastcgi_module 模块使得nginx可以与 fastcgi 服务器通信。比如目前要使得 nginx 支持 php 就得使用 fastcgi技术,在服务器上装上 nginx...

  • nginx模块 ngx_http_autoindex_module

    ngx_http_autoindex_module 模块可以将uri以 / 结尾时,列出里面的文件和目录。Syntax: autoindex on | off; Default: autoindex ...

简介
天降大任于斯人也,必先苦其心志。