文章目录
- 时间戳
- 获取本地时间
- struct tm 结构体
- 高精度的时间
- struct timeval 结构体
- 相关函数
- time()
- localtime()
- gmtime()
- gettimeofday()
- strftime()
- mktime()
- 示例代码
时间戳
时间戳是指计算机中存储的数字型时间。它是以一个特定的时间点作为起点(通常是1970年1月1日0时0分0秒)开始,直到当前时间经过的秒数,即唯一标识了某一个时间的数字。时间戳也被称为日历时间,在linux系统中时间戳是一个long int 类型,可以用time函数获取。
获取本地时间
通过使用 localtime() 函数,可以将时间戳(秒数)转换为 struct tm 结构体,对应本地时区。
通过使用gmtime() 函数,可以将时间戳(秒数)转换为 struct tm 结构体,对应格林尼治标准时间(GMT)。
struct tm 结构体
struct tm {
int tm_sec; // 秒,范围从 0 到 59
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; // 夏令时标识
};
**注意:**在struct tm 中 年份的表示是从1900年开始到现在的年份的个数,使用时需要加1900,才能表示现在的年份。
高精度的时间
通过time函数的得到的时间戳只能精确到秒级别,想要获取高精度时间达到微妙级别需要使用函数 gettimeofday 和结构体struct timeval。
struct timeval 结构体
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
相关函数
time()
#include <time.h>
time_t time(time_t *tloc);
Linux下可以使用time()来查看当前时间,这个函数会计算从1970年1月1号00:00(UTC)到当前的时间跨度。秒级别。
localtime()
struct tm *localtime(const time_t *timep);
将时间戳转化为本地时间
gmtime()
struct tm *gmtime(const time_t *timep);
将时间戳转化为格林尼治标准时间。
gettimeofday()
#include <sys/time.h>
// 调用成功返回0,失败返回-1
int gettimeofday(struct timeval *tv, struct timezone *tz);
Linux下可以使用gettimeofday()来查看当前时间,这个函数会计算从1970年1月1号00:00(UTC)到当前的时间跨度。该函数所算出的时间跨度会存放在第一个参数tv里。时间跨度可以精确到微妙,time_t和suseconds_t的实际类型是long int。日常使用时,只需传第一个参数,第二个参数传NULL(因为linux内核不会使用这个参数)。
strftime()
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
将struct tm 转化为格式化字符串。
mktime()
time_t mktime(struct tm *tm);
所指向的结构转换为自 1970 年 1 月 1 日以来持续时间的秒数,发生错误时返回-1。
示例代码
改代码实现一部分ls命令的功能,会用到时间的转换
getstatus.c
#include "getstatus.h"
#include <bits/types/time_t.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#define FILE_TYPE_MASK 0xF000
typedef unsigned int u32;
char file_type[7]={'p','c','d','b','-','l','s'};
char file_wr[][4]={"---\0","--x\0","-w-\0","-wx\0","r--\0","r-x\0","rw-\0","rwx\0"};
int show_time(time_t time)
{
time_t t = time;
struct tm * p = localtime(&t);
int year = p->tm_year + 1900;
int month = p->tm_mon + 1;
int day = p->tm_mday;
int h = p->tm_hour;
int m = p->tm_min;
int s = p->tm_sec;
printf("%02d月 %02d %04d %02d:%02d ",month,day,year,h,m);
return 0;
}
void get_filestatus(struct stat * status)
{
u32 information = status->st_mode;
//获取文件类型
int tmp = ((information & FILE_TYPE_MASK)>>12)/2;
printf("%c",file_type[tmp]);
//所有者权限
tmp = (information & 0x01c0)>>6;
printf("%s",file_wr[tmp]);
//所有组权限
tmp = (information & 0x0038)>>3;
printf("%s",file_wr[tmp]);
//other
tmp = (information & 0x0007);
printf("%s",file_wr[tmp]);
printf(" %ld ",status->st_nlink);
//获取user name
struct passwd * pwd = getpwuid(status->st_uid);
printf(" %s ",pwd->pw_name);
struct group * gwd = getgrgid(status->st_gid);
printf(" %s ",gwd->gr_name);
printf(" %6ld ",status->st_size);
show_time(status->st_atim.tv_sec);
}
getstatus.h
#ifndef __GETSTATUS_H
#define __GETSTATUS_H
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
void get_filestatus(struct stat *status);
#endif
main.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "getstatus.h"
int main(int argc, char **argv)
{
struct stat st;
if (argc < 2)
{
printf("use: command filename1 filename2 ...\n");
exit(-1);
}
for(int i=1;i<argc;i++)
{
stat(argv[i], &st);
get_filestatus(&st);
printf("%s \n",argv[i]);
}
while(1){}
}
效果
wangju@wangju-virtual-machine:~/learn/filestatus$ ls | xargs -i ./myls {}
-rw-rw-r-- 1 wangju wangju 1491 01月 03 2025 14:33 getstatus.c
-rw-rw-r-- 1 wangju wangju 176 01月 03 2025 15:01 getstatus.h
-rw-rw-r-- 1 wangju wangju 478 01月 03 2025 14:33 main.c
-rwxrwxr-x 1 wangju wangju 17376 01月 03 2025 15:02 myls
-rwxrwxr-x 1 wangju wangju 17376 12月 27 2024 14:17 t
drwxrwxr-x 2 wangju wangju 4096 12月 26 2024 19:40 test
wangju@wangju-virtual-machine:~/learn/filestatus$ ll
总用量 64
drwxrwxr-x 3 wangju wangju 4096 1月 3 15:01 ./
drwxrwxr-x 11 wangju wangju 4096 1月 2 14:50 ../
-rw-rw-r-- 1 wangju wangju 1491 12月 26 19:38 getstatus.c
-rw-rw-r-- 1 wangju wangju 176 1月 3 15:00 getstatus.h
-rw-rw-r-- 1 wangju wangju 478 12月 27 14:17 main.c
-rwxrwxr-x 1 wangju wangju 17376 12月 26 19:38 myls*
-rwxrwxr-x 1 wangju wangju 17376 12月 27 14:17 t*
drwxrwxr-x 2 wangju wangju 4096 12月 26 18:57 test/