linux c时间

日历时间

#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进程凭证(权限)
下一篇: linux系统和进程信息(/proc)
作者邮箱: 203328517@qq.com