前两天写了一个获取时间的文章, 但是为什么又写一篇文章.
1、上一篇 总结的函数少.
2、遇到了问题.
有一天晚上使用gmtime
函数,获取时间出现了26点的情况. 白天的时候就正常了.
2020-4-16 26:35:23
实际时间是:
2020-4-17 2:35:23
3、再次测试
baoshaohua:获取系统当前时间 bao$ ./ctime
sec = Sun Apr 19 01:07:27 2020
str = Sun Apr 19 01:07:27 2020
baoshaohua:获取系统当前时间 bao$ ./gmtime
2020-04-18 25:07:28
2020-04-18 25:07:28
baoshaohua:获取系统当前时间 bao$ ./localtime
2020-04-19 01:07:30
2020-04-19 01:07:30
gmtime转出来的是0时区的标准时间, 输出时间的时候“我” +8
了,
使用localtime
函数获取·分解时间, 当前时区的时间.
#include
#include
int main(int argc, char *argv[]) {
char len[20] = {
0};
time_t timep;
time(&timep);
struct tm *p;
p = gmtime(&timep);
snprintf(len, 20, "%d-%d-%d %d:%d:%d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, 8 + p->tm_hour, p->tm_min, p->tm_sec);
printf("\n%s\n", len);
return 0;
}
运行结果:
baoshaohua:test bao$ ./test
2020-3-25 9:51:42
baoshaohua:test bao$
获取系统当前时间,时间格式 yyyy-MM-dd HH:mm:ss
+++BUG+++
2020-4-16 26:35:23
实际时间是:
2020-4-17 2:35:23
+++BUG+++
在C语言中,获取日期时间的函数 不只是有这一个,还有其他几种
time
(get time in seconds)此函数会返回从公元 1970 年 1 月 1 日的 UTC 时间从 0 时 0 分 0 秒 算起到现在所经过的秒数。
如果 tloc 并非空指针的话,此函数也会将 返回值存到 tloc 指针所指的内存。
参数time_t
就是long
get time in seconds
以秒为单位获取时间
#include
#include
/**
* #include
* time_t time(time_t *tloc); //参数是 time_t 实际是 long
*
* The time() function returns the value of time in seconds since 0 hours, 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time, without including leap seconds.
*/
int main(int arrgc, char const *argv[]){
time_t tloc = 0;
// time_t tt = time(NULL);
time_t tt = time((time_t *)&tloc);
printf("tt [%ld]\n", tt);
printf("tloc [%ld]\n", tloc);
return 0;
}
运行结果:
baoshaohua:test bao$ gcc -o time time.c
baoshaohua:test bao$ ./time
tt [1587116499]
tloc [1587116499]
我不是定义为变量
time_t tloc = 0
,而是定义为指针
time_t *tloc = NULL;
,
定义为变量 time_t tloc = 0
是有空间的.
定义为指针 time_t *tloc = NULL;
这个空间是指针的空间,不是变量的空间.
int main(int arrgc, char const *argv[]){
time_t *tloc = NULL;
time_t tt = time((time_t *)tloc);
printf("tt [%ld]\n", tt);
printf("tloc [%s]\n", tloc);
printf("tloc [%ld]\n", *tloc);
}
输出为:
baoshaohua:获取系统当前时间 bao$ ./time
tt [1587117447]
tloc [(null)]
Segmentation fault: 11
broken-down time | Calendar Time |
---|---|
分解时间 | 日历时间 |
tm 数据类型 |
time_t 数据类型 |
… | 用time_t表示的时间(日历时间)是从一个时间点(例如:1970年1月1日… |
#include
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
time_t mktime(struct tm *tm);
//tm 结构体
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
The members of the tm structure are:
tm_sec The number of seconds after the minute, normally in the range 0 to 59, but can be up to 60 to allow for leap
seconds.
tm_min The number of minutes after the hour, in the range 0 to 59.
tm_hour The number of hours past midnight, in the range 0 to 23.
tm_mday The day of the month, in the range 1 to 31.
tm_mon The number of months since January, in the range 0 to 11.
tm_year The number of years since 1900.
tm_wday The number of days since Sunday, in the range 0 to 6.
tm_yday The number of days since January 1, in the range 0 to 365.
tm_isdst A flag that indicates whether daylight saving time is in effect at the time described. The value is positive
if daylight saving time is in effect, zero if it is not, and negative if the information is not available.
ctime()
、gmtime()
和localtime()
函数都接受数据类型time_t
的参数,该参数表示日历时间。
asctime()
和mktime()
函数都接受一个表示分解时间的参数,它是一个分隔为年、月、日等的表示。
这四个函数asctime()
、ctime()
、gmtime()
和localtime()
返回一个指向静态数据的指针,因此不是线程安全的。
gmtime_r
等函数, 会将结果放在两个“地方”. 一个是返回值的, 你只需要用指针接收;
result
的那个你需要申请内存, 而不是一个tm结构体的指针.(否则,编译没问题,运行段错误)
ctime
(将日历时间转换为以null结尾的字符串)#include
#include
#include
/**
* @brief
* #include
* char * ctime(const time_t *clock);
*
* ctime()将参数 clock 所指的 time_t 结构中的信息转换成真实世界 所使用的时间日期表示方法,然后将结果以字符串形态返回。
* 此函数已经由时区转换成当地时间,字符串格式为“Wed Jun 30 21 :49 08 1993\n”。若再调用相关的时间日期函数,此字符串可能会被破坏。
*/
int main(int argc, char *argv[]) {
char str[30] = {
0};
time_t *clock;
//获取时间,保存到time_t结构体中。在time的返回值(sec)里面有全部秒数
sec = time(clock);
strncpy(str, 32, ctime(clock)); //将time_t类型的结构体中的时间,按照一定格式保存成字符串,
printf("str = %s\n", str);
return 0;
}
运行结果:
baoshaohua:test bao$ gcc -o ctime ctime.c
baoshaohua:test bao$ ./ctime
str = Wed Mar 25 15:50:23 2020
将日历时间转换为以null结尾的字符串
返回值指向一个静态分配的字符串,该字符串可能会被随后对任意日期和时间函数的调用覆盖。
该函数还设置了外部变量tzname、timezone和daylight.
参见tzset(3)
这种方式获取到的时间,格式是固定的,不能满足需求。
ctime_r
char *ctime_r(const time_t *timep, char *buf);
ctime_r
与 ctime
执行相同的操作, 但将字符串存储在用户提供的缓冲区中,该缓冲区至少有26个字节的空间。
不需要设置tzname, timezone, and daylight.
将时间字符串保存在两处, 但是返回值的字符串你只需要传一个指针, buf需要传一个数组的首地址.
int main(int argc, char *argv[]) {
int sec = 0;
char str[30] = {
0};
char str1[30] = {
0};
time_t *clock;
//获取时间,保存到time_t结构体中。在time的返回值(sec)里面有全部秒数
sec = time(clock);
strcpy(str1, ctime_r(clock, str));
printf("sec = %s\n", str1);
printf("str = %s\n", str);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ ./ctime
sec = Sat Apr 18 10:18:07 2020
str = Sat Apr 18 10:18:07 2020
gmtime
(将日历时间 --> 分解时间)#include
#include
/**
* #include
* struct tm * gmtime(const time_t *clock);
*
* gmtime()将参数 clock 所指的 time_t 结构中的信息转换成真实世界 所使用的时间日期表示方法,然后将结果由结构 tm 返回。结构 tm 的定义为:
struct tm {
int tm_sec; //代表目前秒数,正常范围为 0-59,但允许至 61 秒
int tm_min; //代表目前分数,范围 0-59
int tm_hour; //从午夜算起的时数,范围为 0-23
int tm_mday; //目前月份的日数,范围 01-31
int tm_mon; //代表目前月份,从一月算起,范围从 0-11
int tm_year; //从 1900 年算起至今的年数
int tm_wday; //一星期的日数,从星期一算起,范围为 0-6
int tm_yday; //从今年 1 月 1 日算起至今的天数,范围为 0-365 int tm_isdst 日光节约时间的旗标 此函数返回的时间日期未经时区转换,而是 UTC 时间。
int tm_isdst;
};
*/
int main(int argc, char *argv[])
{
time_t timep;
time(&timep);
struct tm *p;
p = gmtime(&timep);
printf("%d\n", p->tm_sec); /*获取当前秒*/
printf("%d\n", p->tm_min); /*获取当前分*/
printf("%d\n", 8 + p->tm_hour); /*获取当前时,这里获取西方的时间,刚好相差八个小时*/
printf("%d\n", p->tm_mday); /*获取当前月份日数,范围是1-31*/
printf("%d\n", 1 + p->tm_mon); /*获取当前月份,范围是0-11,所以要加1*/
printf("%d\n", 1900 + p->tm_year); /*获取当前年份,从1900开始,所以要加1900*/
printf("%d\n", p->tm_yday); /*从今年1月1日算起至今的天数,范围为0-365*/
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ gcc -o gmtime gmtime.c
baoshaohua:获取系统当前时间 bao$ ./gmtime
11
37
11
18
4
2020
108
如果需要组成你需要的时间格式,那么就可以借助 snprintf
函数
gmtime_r
(将日历时间 --> 分解时间)struct tm *gmtime_r(const time_t *timep, struct tm *result);
int main(int argc, char *argv[])
{
time_t timep;
time(&timep);
struct tm *p = NULL;
struct tm *p1 = NULL;
p = calloc(1, sizeof(struct tm));
p1 = gmtime_r(&timep, p);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, 8 + p->tm_hour, p->tm_min, p->tm_sec);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + p1->tm_year, 1 + p1->tm_mon, p1->tm_mday, 8 + p1->tm_hour, p1->tm_min, p1->tm_sec);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ gcc -o gmtime gmtime.c
baoshaohua:获取系统当前时间 bao$ ./gmtime
2020-04-18 11:40:14
2020-04-18 11:40:14
p 和 p1 都有分解时间. p 是 ‘我’ 申请的空间, p1是库函数gmtime_r
申请.
返回值指向一个静态分配的结构,
localtime
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
#include
#include
int main(int argc, char const *argv[]){
time_t timep;
time(&timep);
struct tm *t = NULL;
t = localtime(&timep);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ gcc -o localtime localtime.c
baoshaohua:获取系统当前时间 bao$ ./localtime
2020-04-18 11:32:16
gmtime
不同的是, 时间没有+8
localtime_r
int main(int argc, char const *argv[]){
time_t timep;
time(&timep);
struct tm *t = NULL;
struct tm t1 = {
0};
t = localtime_r(&timep, &t1);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t1.tm_year, 1 + t1.tm_mon, t1.tm_mday, t1.tm_hour, t1.tm_min, t1.tm_sec);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ gcc -o localtime localtime.c
baoshaohua:获取系统当前时间 bao$ ./localtime
2020-04-18 11:44:23
2020-04-18 11:44:23
time_t mktime(struct tm *tm);
#include
#include
int main(int argc, char const *argv[]){
time_t timep;
time_t result;
long sec = time(&timep);
struct tm *t = NULL;
t = localtime(&timep);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
result = mktime(t);
printf("result [%ld]\n", result);
printf("sec [%ld]\n", sec);
return 0;
}
baoshaohua:获取系统当前时间 bao$ gcc -o mktime mktime.c
baoshaohua:获取系统当前时间 bao$ ./mktime
2020-04-18 12:27:16
result [1587184036]
sec [1587184036]
asctime
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
#include
#include
int main(int argc, char const *argv[]){
time_t timep;
long sec = time(&timep);
struct tm *t = NULL;
char *result = NULL;
t = localtime(&timep);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
result = asctime(t);
printf("result [%s]\n", result);
printf("sec [%ld]\n", sec);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ gcc -o asctime asctime.c
baoshaohua:获取系统当前时间 bao$ ./asctime
2020-04-18 12:15:09
result [Sat Apr 18 12:15:09 2020
]
sec [1587183309]
asctime
的返回值不需要调用者 申请空间.asctime_r
int main(int argc, char const *argv[]){
time_t timep;
long sec = time(&timep);
struct tm *t = NULL;
char result[32] = {
0};
t = localtime(&timep);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
asctime_r(t, result);
printf("result [%s]\n", result);
printf("sec [%ld]\n", sec);
return 0;
}
gettimeofday
#include
#include
/**
* @brief
* #include
* int gettimeofday(struct timeval * tv, struct timezone * tz)
*
* gettimeofday () 会把目前的时间放到 tv 所指的结构返回,当地时区 的信息则放到 tz 所指的结构中。
*
* struct timeval {
* time_t tv_sec; // seconds since Jan. 1, 1970
* suseconds_t tv_usec; // and microseconds
* };
*
*/
int main(int argc, char *argv[]) {
struct timeval tv;
struct timezone tz;
time_t * tloc;
int sec = time((time_t *)tloc);
printf("\n%d\n\n", sec);
gettimeofday(&tv, NULL);
printf("\n\n%ld\n\n", tv.tv_sec);
return 0;
}
运行结果:
baoshaohua:获取系统当前时间 bao$ ./gettimeofday
1587034229
1587034229