我大概是乏了,横竖都开心不起来,站起身来皱了眉头,这悲伤是没来由的。作为一个曾经长期掌控不了系统时间的初级程序猿,在经过几天的探索以后,心血来潮总结下来分享给小伙伴们。小伙伴们或许会很期待吧,一篇博客如何让自己成为掌控时间的强者呢?多说无益,开始正文!
目录
今天是几号?
time_t 型:日历时间
time 函数:以日历时间的形式来获取当前时间
tm 结构体:分解时间(撕裂时间)
localtime 函数:把日历时间转换成表示本地时间的分解时间
gmtime 函数:把日历时间转换成UTC分解时间
asctime 函数:把分解时间转换成字符串
ctime 函数:把日历时间转换成字符串
difftime 函数:求时间差
求星期
mktime 函数:两极反转
完结
先来上本篇博客的第一段代码,小伙伴们来学习一下如何获取当前日期及时间:
//time01
#include <stdio.h>
#include <time.h>
void put_date(const struct tm* timer)
{
char* wday_name[] = { "日","一","二","三","四","五","六" };
printf("%4d年%02d月%02d日(%s)%02d时%02d分%02d秒", timer->tm_year + 1900, //年
timer->tm_mon + 1, //月
timer->tm_mday, //日
wday_name[timer->tm_wday], //星期
timer->tm_hour, //时
timer->tm_min, //分
timer->tm_sec); //秒
}
int main()
{
time_t current; //日历时间
struct tm* timer; //分解时间(结构体)
time(¤t); //获取当前时间
timer = localtime(¤t); //转换成分解时间(本地时间)
printf("当前日期和时间是");
put_date(timer);
printf("。\n");
return 0;
}
time_t 型,又称为日历时间,其实它很像int型和double型一样,能够进行加减乘除运算的算数型。具体等同于哪个类型取决于编程环境(不光决定日历时间的类型,还决定了其具体的值)。使用它需要加上<time.h>头文件定义。在大多数编译环境中把time_t 型等同于int型或long型,以格林尼治标准时间,也就是1970年1月1日0时0分0秒后经过的秒数作为日历时间的具体值。
且看下表:
time | |
头文件 | #include <time.h> |
格式 | time_t time(time_t *timer); |
功能 | 决定当前的日历时间。未定义该值的表现形式 |
返回值 | 用所在编译环境中的最佳逼近返回求出的日历时间。若日历时间无效则返回值(time_t)1,当timer不为空指针时,将返回值赋给timer指向的对象。 |
此函数在求出日历时间的基础上,把日历时间存入参数timer指向的对象中,同时返回日历时间。因此我们可以根据不同的用途和个人喜好来选择各种调用方式。
我们通过运用time(¤t); ,把指向变量current的指针作为参数传递给了time函数。
尝试一下用time_t型来表示时间的我们知道,它所表示的是我们极其不易理解的:
因此,我们可以使用另外一个表示方法,就是被成为撕裂时间的tm结构体类型。
我们把tm 结构体拿出来看看:
struct tm{
int tm_sec; //秒(0-61)
int tm_min; //分(0-59)
int tm_hour; //时(0-23)
int tm_mday; //日(0-31)
int tm_mon; //从一月开始的月份(0-11)
int tm_year; //从1900开始的年份
int tm_wday; //星期:星期日-星期六(0-6)
int tm_yday; //从1月1日开始的天数(0-365)
};
小伙伴们可以通过代码中的注释来理解各个成员表示的值。而当我们在浏览到秒的成员tm_min的值设在0-61,是因为考虑到了”闰秒“。
localtime 函数(通过tm结构体)用于把日历时间的值转换成分解时间。
localtime | |
头文件 | #include <time.h> |
格式 | struct tm*localtime(const time_t *timer); |
功能 | 把timer指向的日历时间转换成用本地时间表示的分解时间 |
返回值 | 返回指向转换后的对象的指针 |
正如locattime的字面以四所示,转换后得到的是本地时间。我们来看看它的表示图:
最后我们再来分析一下 time01 程序。
(1)在main函数中,我们运用了time 函数以time_t 型的日历时间的形式获取当前时间,将其转换成分解时间,即tm 结构体。
(2)如何再使用 put_date 接受转换后的结构,并用公历纪元显示分解时间;
(3)最后,在tm_year 桑加上1900,在tm_mon上加上1,由于表示星期的tm_wday从星期日到星期六分别对应0到6,因此可以利用数组wday_name 将其转换后中文字符串”日“,”一“,…”六“并显示出来。
只讲本地时间的话可谓太吝啬了,接下来我将给小伙伴们带来协调时间时(即UTC)。
gmtime 函数是用来执行UTC的函数,且看下表;
gmtime | |
头文件 | #include <time.h> |
格式 | struct tm *gmtime(const time_t *timer); |
功能 | 把timer指向的日历时间转换成用协调时间时表示的分解时间 |
返回值 | 返回指向转换后的对象的指针 |
我们来看看如何运用gmtime函数,代码其实跟 time01 如出一辙:
//time02
#include <stdio.h>
#include <time.h>
void put_date(const struct tm* timer)
{
char* wday_name[] = { "日","一","二","三","四","五","六" };
printf("%4d年%02d月%02d日(%s)%02d时%02d分%02d秒", timer->tm_year + 1900,
timer->tm_mon + 1,
timer->tm_mday,
wday_name[timer->tm_wday],
timer->tm_hour,
timer->tm_min,
timer->tm_sec);
}
int main()
{
time_t current;
struct tm* timer;
time(¤t);
timer = gmtime(¤t);
printf("当前日期和时间用UTC表示是");
put_date(timer);
printf("。\n");
return 0;
}
其实就是把timer = localtime(¤t); 改为timer = gmtime(¤t); 。
再给小伙伴们分享一个函数,它可以把分解时间转换成字符串,能简单地表示出当前日期和时间,何乐而不为呢?且看下面代码:
//time03
#include <stdio.h>
#include <time.h>
int main()
{
time_t current = time(NULL);
printf("当前日期和时间:%s", asctime(localtime(¤t)));
return 0;
}
asctime 函数是把分解时间转换成字符串形式的函数。它生成和返回的字符串从左到右按星期/月/日/时/分/秒/年的顺序排列,用空白字符与冒号”:“隔开。
我们可以看到,星期和月中分别存有其英语单词开头的3个字母(开头的字母是大写字母,而第2个和第3个是小写字母)。我们再来看看它的表:
asctime | |
头文件 | #include <time.h> |
格式 | char *asctime(const struct tm *timeptr); |
功能 |
把timeptr指向的结构体的分解时间转换成下面这种形式的字符串 Sun Apr 10 13:13:09:00 2022 |
返回值 | 返回指向转换后的对象的指针 |
使用asctime函数时,我们为了把time_t型的日历时间转换成tm 结构体的分解时间,需要实现调用localtime 函数。这样一来,把日历时间转换成字符串就需要两个步骤了,未免太过于繁琐。ctime 函数就不一样了,只需一步便可!
//time04
#include <stdio.h>
#include <time.h>
int main()
{
time_t current = time(NULL);
printf("当前日期和时间:%s", ctime(¤t));
return 0;
}
ctime 表如下:
ctime | |
头文件 | #include <time.h> |
格式 | char *ctime(const time_t *timer); |
功能 | 把timer指向的日历时间转换成与asctime函数具有相同字符串形式的本地时间,相当于asctime(localtime(timer)) |
返回值 | 返回以分解时间为实际参数的asctime函数返回的指针 |
接下来我讲给你们带来如何利用time函数获取的日历时间来计算处理时间。先上代码:
//time05
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b, c, d;
int x;
time_t start, end;
srand(time(NULL));
a = rand() % 100;
b = rand() % 100;
c = rand() % 100;
d = rand() % 100;
printf("%d+%d+%d+%d等于多少:", a, b, c, d);
start = time(NULL);
while (1)
{
scanf("%d", &x);
if (x == a + b + c + d)
break;
printf("回答错误!!\n请重新输入:");
}
end = time(NULL);
printf("用时%.0f秒。\n", difftime(end, start));
return 0;
}
printf("用时%.0f秒。\n", difftime(end, start)); 通过调用difftime 函数用来求两个日历时间的差。它的用法极其简单,把两个time_t 型的值作为参数(end-start)给出就行,并以秒为单位的double型数值的形式返回时间差。
我们再来看看difftime的表:
difftime | |
头文件 | #include <time.h> |
格式 | double difftime(time_t time1,time_t time0); |
功能 | 计算两个日历时间的差time1 - time0 |
返回值 | 以秒为单位表示求得的时间差,将其作为double 型返回 |
前面讲述了如果将日历时间转换成分解时间,现在我再来讲讲如何将本地时间的分解时间转换成日历时间,那就是使用mktime 函数,它的功能与localtime 函数进行的转换正好相反。
而且,这函数还带来了意外之喜。它可以计算并设定结构体的星期和一年中经过的天数的值。利用该功能的话,咱只需设定分解时间的年/月/日并调用mktime 函数,就能求出对应的星期。
我们来看看它的流程图:
这可真是两极反转啊!
最后,用一段华丽的代码了却此博客:
//time06
#include <time.h>
#include <stdio.h>
int dayofweek(int year, int month, int day)
{
struct tm t;
t.tm_year = year - 1900;
t.tm_mon = month - 1;
t.tm_mday = day;
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = -1;
if (mktime(&t) == (time_t)-1)
return -1;
return t.tm_wday;
}
int main()
{
int y, m, d, w;
char* ws[] = { "日","一","二","三","四","五","六" };
printf("求星期。\n");
printf("年:"); scanf("%d", &y);
printf("月:"); scanf("%d", &m);
printf("日:"); scanf("%d", &d);
w = dayofweek(y, m, d);
if (w != -1)
printf("这一天是星期%s。\n", ws[w]);
else
printf("无法求出星期。\n");
return 0;
}
time06 中定义的dayofweek 函数会根据接受的年/月/日这3个值来生成分解时间,然后再调用mktime 函数,之后函数会通过”附赠“的功能直接返回成员函数tm_wday 中设定的值,值为0是星期日……
此外,mktime函数返回错误时,说明程序有可能求出了错误的星期数值,因此函数dayofweek 会返回 -1。
很感激阅读到这里的你,相信阅读完的你已经成为了掌控时间的强者了吧!精彩并不止于这些,学有余力的小伙伴可以看看下面这些博客,都是有着极多的技巧与干货❤!
C语言小游戏(一)----猜数游戏_施律.的博客-CSDN博客_c语言猜数游戏次数限制
《斗破CPP》 第壹章 ---- 初窥CPP_施律.的博客-CSDN博客
《斗破CPP》 第贰章(上) ---- 初识分支句_施律.的博客-CSDN博客
如果觉得本篇博客对正在学习编程的你有帮助的话,请给施律.多一点的支持与关注!未来的一段时间里施律.将和小伙伴们一起在编程的道路是越来越远,希望下次的我能为大家奉上更好的博客内容,也希望下次的博客有你!