Linux C语言 19-时间获取

Linux C语言 19-时间获取

本节关键字:Linux、C语言、时间、随机数、获取毫秒
相关C库函数:time、localtime、rand、srand、printf

计算机时间的由来

UNIX操作系统根据计算机产生的年代和应用采用1970年1月1日作为UNIX的纪元时间,1970年1月1日0点作为计算机表示时间的是中间点,将从1970年1月1日开始经过的秒数用一个整数存放,这种高效简洁的时间表示方法被称为“Unix时间纪元”,向左和向右偏移都可以得到更早或者更后的时间。
在实际开发中,对日期和时间的操作场景非常多,例如程序启动和退出的时间,程序执行任务的时间,数据生成的时间,数据处理的各环节的时间等,无处不在。
在学习时间之前,请把Linux操作系统的时区设置为中国上海时间。

相关库函数

时间获取
#include <time.h>
// 返回自大纪元1970-01-01 00:00:00+0000(UTC)以来的秒数。如果t不是NULL,则返回值也存储在t指向的内存中。成功时,返回自Epoch以来的时间值(以秒为单位)。出现错误时,将返回((time_t)-1),并适当设置errno。
time_t time(time_t *t);
// 将秒数值转化为本地时间的结构体描述
struct tm *localtime(const time_t *timep);
// 将秒数值转换为表单的以NULL结尾的字符串
char *ctime(const time_t *timep);

struct tm
{
	int tm_sec;         /* seconds 0到59 */
	int tm_min;         /* minutes 0到59 */
	int tm_hour;        /* hours 0到23 */
	int tm_mday;        /* day of the month 0到31 */
	int tm_mon;         /* month 0到11 */
	int tm_year;        /* year 自1900年以来的年数 */
	int tm_wday;        /* day of the week 自周日以来的天数 0到6 */
	int tm_yday;        /* day in the year 自1月1日以来的天数 0到365 */
	int tm_isdst;       /* daylight saving time 该值为正,夏令时有效;该值为0夏令时无效;该值为tive,信息不可用 */
};
随机数
#include <stdlib.h>
// 设置随机数种子,只需设置依次即可,一般以时间作为种子
void srand(unsigned int seed);
// 获取一个随机数
int rand(void);

API使用示例

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    int i;
    time_t sec;
    time_t sec_rc;
    
    sec_rc = time(&sec);
    printf("sec=%d, sec_rc=%d\n", sec, sec_rc);
    
    sec = 0;
    sec = time(0);
    printf("sec=%d\n", sec);
    
    char *sTimep = NULL;
    struct tm *ptime = NULL;
    ptime = localtime(&sec);
    printf("%04u年%02u月%02u日 %02u时%02u分%02u秒\n", 
        ptime->tm_year+1900,ptime->tm_mon+1, ptime->tm_mday,
        ptime->tm_hour, ptime->tm_min, ptime->tm_sec );
    
    sTimep = ctime(&sec);
    printf("sTimep: %s\n", sTimep);
    
    
    printf("未设置随机种子\n");
    for (i=0; i<5; i++)
        printf("rand=%d\n", rand());
    
    printf("设置一次随机种子\n");
    srand((unsigned int)time(0));
    for (i=0; i<5; i++)
        printf("rand=%d\n", rand());
    
    printf("设置多次随机种子\n");
    for (i=0; i<5; i++)
    {
        srand((unsigned int)time(0));
        printf("rand=%d\n", rand());
    }
    
    // 获取m到n之间的随机数  rand() % n + m
    printf("获取1到100之间的随机数\n");
    for (i=0; i<20; i++)
        printf("%d  ", rand() % 100 + 1);
    printf("\n");
    
    return 0;
}

/** 运行结果:
sec=1700211276, sec_rc=1700211276
sec=1700211276
2023年11月17日 16时54分36秒
sTimep: Fri Nov 17 16:54:36 2023
未设置随机种子
rand=1804289383
rand=846930886
rand=1681692777
rand=1714636915
rand=1957747793
设置一次随机种子
rand=359111267
rand=609384155
rand=1676377208
rand=120486859
rand=1211057934
设置多次随机种子
rand=359111267
rand=359111267
rand=359111267
rand=359111267
rand=359111267
获取1到100之间的随机数
56  9  60  35  40  55  1  20  4  14  8  94  97  20  22  68  11  9  12  41
*/

本节彩蛋 适配Windows和Unix

微秒定时器
void usleep(unsigned long usec)
{
#if defined (WIN32)
    Sleep(usec / 1000);
#elif defined (__unix)
    struct timeval tv;

    while (1)
{
        tv.tv_sec = usec / 1000000;
        tv.tv_usec = usec % 1000000;

        if (select(0, 0, 0, 0, &tv) < 0) 
{
            if (getLastError() == EINTR)
{
                usec = usec / 2;
                if(usec >= 50000)
                    continue; 
            }
        }
        break;
    }
#endif
}
获取精确到毫秒的时间
typedef struct {
    int tm_year;
    int tm_mon;
    int tm_day;
    int tm_hour;
    int tm_min;
    int tm_sec;
    int tm_msec;
} tm_msec;
tm_msec *get_curtime()
{
    static tm_msec tm;
#ifdef __unix
    struct timeval  tmptimeval;
    gettimeofday(&tmptimeval,NULL);
    tm.tm_sec  = tmptimeval.tv_sec;
    tm.tm_msec = tmptimeval.tv_usec/1000;
#endif

#ifdef _WIN32
    tm.tm_sec = (time_t)time(NULL);
    SYSTEMTIME systime;
    ::GetSystemTime(&systime);
    tm.tm_msec = systime.wMilliseconds;
#endif

    time_t tnow = time(0);
    struct tm *ptm = localtime(&tnow);
    tm.tm_year = ptm->tm_year+1900;
    tm.tm_mon  = ptm->tm_mon+1;
    tm.tm_day  = ptm->tm_mday;
    tm.tm_hour = ptm->tm_hour;
    tm.tm_min  = ptm->tm_min;
    tm.tm_sec  = ptm->tm_sec;

    return &tm;
}
  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值