目录
1.time和ctime获取当前时间
time:获取自 Epoch(1970-01-01 00:00:00 UTC) 到现在的秒数。
time_t time(time_t *t);
功能:
获得1970年1月1日到现在的秒数
参数:
t:存放秒数空间的首地址
返回值:
成功返回1970年1月1日到现在的秒数
失败返回-1
char *ctime(const time_t *timep);
功能:
将秒数转换为字符串时间
参数:
timep:1970年1月1日到现在的秒数
返回值:
成功返回时间字符串首地址
失败返回NULL
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
//获取当前时间time
void test1()
{
printf(" test1() 开始执行\n");
time_t now = time(NULL);
// 输出结果
printf("1970-01-01 00:00:00 UTC到现在 %ld 秒\n", now);
printf(" test1() 结束执行\n");
}
//获取当前时间ctime
void test2()
{
printf(" test2() 开始执行\n");
char *ptmp = NULL;
time_t t;
ptmp = ctime(&t);
printf("时间字符串 = %s\n", ptmp);//时间字符串
printf(" test2() 结束执行\n");
}
int main(int argc, char const *argv[])
{
test1();
test2();
return 0;
}
运行结果:
2.gettimeofday获取时间(微秒级)
在 Linux 系统编程中,gettimeofday 函数用于获取当前时间(微秒级精度),返回自 Epoch(1970-01-01 00:00:00 UTC) 以来的时间值。
函数原型:
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
参数:
tv:输出参数,接收时间的 struct timeval 结构体指针。
tz:时区信息,已废弃,应设为 NULL。
返回值:
成功返回 0,失败返回 -1 并设置 errno(极少失败)。
timeval 结构体:
struct timeval
{
time_t tv_sec; // 秒(自 1970-01-01 00:00:00 UTC 以来的秒数)
suseconds_t tv_usec; // 微秒(0 ~ 999,999)
};
2.1计算程序执行时间差
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
/*
//结构体原型
struct timeval
{
time_t tv_sec; // 秒
suseconds_t tv_usec; // 微秒
};
*/
//计算程序执行时间差
void test1()
{
printf(" test1() 开始执行\n");
struct timeval start, end; //定义开始时间、结束时间结构体
// 记录开始时间
gettimeofday(&start, NULL);// 第二个参数时区(通常置 NULL)
long i;
for(i = 0; i < 1000000 ; i++)
{
//for循环累加,测试耗时
}
// 记录结束时间
gettimeofday(&end, NULL);
// 计算时间差
long seconds = end.tv_sec - start.tv_sec;
long micros = end.tv_usec - start.tv_usec;
if (micros < 0)
{
seconds--;
micros += 1000000;
}
// 输出结果
printf("取消 耗时:%ld 秒 %ld 微秒\n", seconds, micros);
printf(" 耗时(秒):%.6f\n", seconds + micros / 1e6);
printf(" test1() 结束执行\n");
}
int main(int argc, char const *argv[])
{
test1();
return 0;
}
运行结果:
2.2获取当前时间
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
//获取当前时间
void test2()
{
printf(" test2() 开始执行\n");
//定义时间结构体
struct timeval tv;
if (gettimeofday(&tv, NULL) == 0)
{
printf("1970-01-01 00:00:00 UTC到现在 %ld 秒 %ld 微秒\n", tv.tv_sec, tv.tv_usec);
}
printf(" test2() 结束执行\n");
}
#if 0
// struct tm *localtime(const time_t *timep);
struct tm {
int tm_sec; // 秒 [0-60]
int tm_min; // 分 [0-59]
int tm_hour; // 时 [0-23]
int tm_mday; // 日 [1-31]
int tm_mon; // 月 [0-11]
int tm_year; // 年(自 1900)
int tm_wday; // 星期 [0-6]
int tm_yday; // 年中的第几天 [0-365]
int tm_isdst; // 夏令时标志
};
#endif
//转换为可读时间
void test3()
{
printf(" test3() 开始执行\n");
struct timeval tv;
gettimeofday(&tv, NULL);
// 转换为本地时间
struct tm tm_info;
localtime_r(&tv.tv_sec, &tm_info); // 线程安全版本
char buffer[64] = "";
//年-月-日-时-分-秒
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm_info);
printf("当前时间:%s %06ld\n", buffer, tv.tv_usec);//微妙
printf(" test3() 结束执行\n");
}
int main(int argc, char const *argv[])
{
test2();
test3();
return 0;
}
运行结果:
3. clock_gettime获取时间(纳秒级)
函数原型:
#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);
参数:
clk_id:时钟源标识符(见下方 时钟源类型 说明)。
tp:输出参数,接收时间的 struct timespec 结构体指针。
返回值:
成功返回 0,失败返回 -1 并设置 errno(如 EINVAL 无效时钟源)。
struct timespec
{
time_t tv_sec; // 秒(自 1970-1-1 以来的秒数)
long tv_nsec; // 纳秒(0 ~ 999,999,999)
};
3.1时钟源类型 (clk_id
)
NTP(Network Time Protocol,网络时间协议)
时钟源 | 特性说明 |
---|---|
CLOCK_REALTIME |
系统实时时间(可被用户或 NTP 修改),适合记录时间戳 |
CLOCK_MONOTONIC |
单调递增时间(不受系统时间修改影响),适合测量时间间隔 |
CLOCK_MONOTONIC_RAW |
类似 CLOCK_MONOTONIC ,但不受 NTP 调整影响(Linux 特有) |
CLOCK_PROCESS_CPUTIME_ID |
进程消耗的 CPU 时间(包括所有线程) |
CLOCK_THREAD_CPUTIME_ID |
线程消耗的 CPU 时间 |
3.2计算程序执行时间差
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
/*
struct timespec
{
time_t tv_sec; // 秒(自 1970-1-1 以来的秒数)
long tv_nsec; // 纳秒(0 ~ 999,999,999)
};
*/
//计算程序执行时间差
void test1()
{
printf(" test1() 开始执行\n");
struct timespec start, end; //定义开始时间、结束时间结构体
// 记录开始时间
clock_gettime(CLOCK_MONOTONIC, &start);
long i;
for(i = 0; i < 1000000 ; i++)
{
//for循环累加,测试耗时
}
// 记录结束时间
clock_gettime(CLOCK_MONOTONIC, &end);
// 计算时间差
long seconds = end.tv_sec - start.tv_sec;
long nanoseconds = end.tv_nsec - start.tv_nsec;
if (nanoseconds < 0)
{ // 处理纳秒借位
seconds--;
nanoseconds += 1000000000L;
}
double elapsed = seconds + nanoseconds / 1e9;
printf("耗时:%.9f 秒 %ld 纳秒 \n", elapsed , nanoseconds );
printf(" test1() 结束执行\n");
}
int main(int argc, char const *argv[])
{
test1();
return 0;
}
运行结果:
3.3获取当前时间
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
//获取当前时间
void test2()
{
printf(" test2() 开始执行\n");
//定义时间结构体
struct timespec tv;
if (clock_gettime(CLOCK_REALTIME, &tv) == 0)
{
printf("1970-01-01 00:00:00 UTC到现在:共 %ld 秒 %ld 纳秒\n", tv.tv_sec, tv.tv_nsec);
}
printf(" test2() 结束执行\n");
}
#if 0
// struct tm *localtime(const time_t *timep);
struct tm {
int tm_sec; // 秒 [0-60]
int tm_min; // 分 [0-59]
int tm_hour; // 时 [0-23]
int tm_mday; // 日 [1-31]
int tm_mon; // 月 [0-11]
int tm_year; // 年(自 1900)
int tm_wday; // 星期 [0-6]
int tm_yday; // 年中的第几天 [0-365]
int tm_isdst; // 夏令时标志
};
#endif
//转换为可读时间
void test3()
{
printf(" test3() 开始执行\n");
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
// 转换为本地时间(线程安全版本)
struct tm tm_info;
localtime_r(&ts.tv_sec, &tm_info);
char buffer[64] = "";
//年-月-日-时-分-秒
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm_info);
printf("当前时间:%s-%09ld 纳秒\n", buffer, ts.tv_nsec);//纳秒
printf(" test3() 结束执行\n");
}
int main(int argc, char const *argv[])
{
test2();
test3();
return 0;
}
运行结果: