time.h是C标准函数库中获取时间与日期、对时间与日期数据操作及格式化的头文件。
返回值类型
- size_t:适合保存sizeof的结果,类型为unsigned int(%u)
- clock_t:适合存储处理器时间的类型,一般为unsigned long(%lu)
- time_t:适合储存日历时间类型,一般情况下是long。(%ld)
- struct tm:保存时间和日期的结构
// 原文注释更容易理解变量的命名
struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11 */ // +1
int tm_year; /* The number of years since 1900 */ // +1900
int tm_wday; /* day of the week, range 0 to 6 */ // +1
int tm_yday; /* day in the year, range 0 to 365 */ // +1
int tm_isdst; /* daylight saving time */
};
宏定义
- NULL:空指针
- CLOCKS_PER_SEC:其值为1000,表示一秒CPU运行的时钟周期数为1000个,相当于1ms一个时钟周期,因此一般说操作系统的单位是毫秒。
time
功能:返回当前日历时间值,这个值是将时间按照一定逻辑计算得来的
- 年数 = 天数 * 小时 * 分钟 * 秒(年数 = 365 * 24 * 60 * 60)
- 得到的日历时间值除于年数,得到结果为自1970年1月1日后经历得年数
函数原型:time_t time(time_t *timer)
返回值:返回自纪元(00:00:00 UTC,1970 年 1 月 1 日)以来的时间,以秒为单位。如果timer不为 NULL,则返回值也存储在变量 timer 中。time_t类型,一般情况下是长整型。(%ld)
参数:为指针类型(一般传入NULL),秒值将存储在指针中。
- time_t now = time(NULL); // 等价为time(&now);
注意:
- 注意区分struct tm中的1900年
-
返回当前日历时间值
#include <stdio.h> #include <time.h> int main () { time_t now = time(NULL); printf("The final resultl is %ld\n", now); return(0); }
得到的结果为:The final resultl is 1704711506
1704711506 / 365 / 24 / 60 / 60 结果约等于54,加上1970后即为2024
clock
功能:记录程序开始以来使用的时钟周期数,可以记录某段程序执行耗时
函数原型:clock_t clock(void)
返回值:返回 程序开始以来使用的时钟周期数,失败则返回-1。clock_t类型(%ld)
-
计算一段代码所需要的时间
#include <time.h> #include <stdio.h> int main () { clock_t start_t, end_t; double total_t; int i; start_t = clock(); printf("Going to scan a loop, start_t = %ld\n", start_t); for(i=0; i< 50000000; i++); end_t = clock(); printf("End of the big loop, end_t = %ld\n", end_t); total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC; // 得到的结果是以 秒 为单位的 printf("Total time taken by CPU: %f\n", total_t ); printf("Exiting of the program...\n"); return(0); }
difftime
功能:返回 time1 和 time2 之间的秒差,即 (time1 - time2)。 这两个时间以日历时间为单位指定,表示自纪元(1970 年 1 月 1 日 00:00:00,协调世界时 (UTC))以来经过的时间。
函数原型:double difftime(time_t time1, time_t time2)
参数:
- time1 − 这是结束时间time_t对象。
- time2 − 这是开始时间time_t对象
返回值: time1 和 time2 之间的秒差作为双精度值返回
-
计算一段代码所需要的时间
#include <stdio.h> #include <time.h> int main () { time_t start_t, end_t; double diff_t; printf("Starting of the program...\n"); time(&start_t); printf("Sleeping for 5 seconds...\n"); sleep(5); time(&end_t); diff_t = difftime(end_t, start_t); printf("Execution time = %f\n", diff_t); // 结果就是以 秒 为单位的 printf("Exiting of the program...\n"); return(0); }
-
my_difftime
double my_difftime(time_t time1, time_t time2){ return (double)(time1 - time2); }
localtime
功能:C 库函数 struct tm localtime(const time_t timer) 使用计时器**指向的时间,用表示相应本地时间的值填充 tm 结构。timer 的值被分解为结构 tm,并以当地时区表示。
函数原型:struct tm *localtime(const time_t *timer)
参数:timer是指向表示日历时间的time_t值的指针,即传入time_t类型的地址。
返回值:返回指向填充了时间信息的 tm 结构的指针,失败则返回NULL。
-
获取当前日期(当前的和多少天之后的,多少天之前的)
#include <stdio.h> #include <time.h> void GetTime(){ time_t now = time(NULL); // 获取当前时间状态 // now += 10 * 24 * 60 * 60; // 获取十天后的时间状态(天 * 时 * 分 * 秒) // now -= 10 * 24 * 60 * 60; // 获取十天前的时间状态(天 * 时 * 分 * 秒) struct tm *info = localtime(&now); int year = info->tm_year + 1900; int month = info->tm_mon + 1; int day = info->tm_mday; int hour = info->tm_hour; int minute = info->tm_min; int second = info->tm_sec; printf("Current time: %d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second); } int main(){ GetTime(); return 0; }
mktime
功能:根据本地时区将 timeptr 指向的结构转换为time_t值。
函数原型:time_t mktime(struct tm *timeptr)
参数:timeprt 是指向结构体tm的指针,即传入struct tm类型的地址。(tm在上面有介绍)
返回值:此函数返回与作为参数传递的日历时间相对应的time_t值。出错时,返回 -1 。
-
将日期转为时间状态值
#include <stdio.h> #include <time.h> #include <math.h> // for abs // 将日期转为time_t // 利用这个函数,可以计算两个日期之间相隔多少天 time_t tm_convert(int year, int month, int day, int hour, int minute, int second) { struct tm time_convert; time_convert.tm_year = year - 1900; time_convert.tm_mon = month - 1; time_convert.tm_mday = day; time_convert.tm_hour = hour; time_convert.tm_min = minute; time_convert.tm_sec = second; return mktime(&time_convert); } void DiffDay() { time_t start = tm_convert(2023, 12, 15, 0, 0, 0); time_t end = tm_convert(2002, 5, 19, 0, 0, 0); double diff = difftime(start, end); int day = (int)(diff / (24 * 60 * 60)); // 每天所有的秒数 printf("相隔%d天.\n", abs(day)); } int main() { DiffDay(); return 0; }
ctime
功能:返回一个基于参数 timer 的、带有日期信息的字符串,其中包含人类可读格式的日期和时间信息,表示 localtime。
函数原型:char *ctime(const time_t *timer)
返回值:返回一个字符串指针,失败则通常返回NULL。返回的字符串采用以下格式:Www Mmm dd hh:mm:ss yyyy,其中 Www 是工作日,Mmm 是以字母表示的月份,dd 是月份的日期**,hh:mm:ss** 是时间,yyyy 是年份。
参数: 指向包含日历时间的time_t对象的指针。
-
获取当前日期
#include <stdio.h> #include <time.h> int main () { time_t now = time(NULL); printf("Current time = %s", ctime(&now)); return(0); }
- 结果
Current time = Tue Jan 09 00:00:17 2024
- 结果
asctime
功能:返回一个字符串指针。其中包含人类可读格式的日期和时间信息,表示localtime
函数原型:char *asctime(const struct tm *timeptr)
参数:是指向struct tm的一个指针
返回值:此函数返回一个 C 字符串,失败则通常返回NULL。返回的字符串格式为:www Mmm dd hh:mm:ss yyyy,其中 Www 是工作日,Mmm 是字母中的月份,dd 是月份的日期,hh:mm:ss 是时间,yyyy 是年份。
小项目
-
制作简易时钟
/* 制作的一个能显示时间的简易时钟 */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <windows.h> // 带颜色的打印函数 void print_with_color(char *str, int color) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, color); printf("%s", str); SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } int main(){ while(1){ /* 这两个放在外面的话,就不能一直获取当前时间了 */ time_t t = time(NULL); struct tm *now = localtime(&t); char str_t[100]; sprintf(str_t, "------------------------\n"); print_with_color(str_t, FOREGROUND_BLUE | FOREGROUND_INTENSITY); sprintf(str_t, "| %d/%02d/%02d %02d:%02d:%02d |\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec); print_with_color(str_t, FOREGROUND_GREEN | FOREGROUND_INTENSITY); sprintf(str_t, "------------------------\n"); print_with_color(str_t, FOREGROUND_BLUE | FOREGROUND_INTENSITY); Sleep(1000); system("cls"); } return 0; } /* 1. print_with_color() 函数:用于将字符串打印到控制台并设置颜色。 2. time() 函数:获取当前的时间戳。 3. localtime() 函数:将时间戳转换为本地时间。 4. sprintf() 函数:根据格式化字符串生成一个字符串。 5. FOREGROUND_BLUE、FOREGROUND_GREEN、FOREGROUND_RED、FOREGROUND_INTENSITY 常量:设置文本颜色。 6. Sleep() 函数:暂停一段时间,单位是毫秒。 7. system("cls"):清空控制台。 在主函数中,程序使用了一个死循环,不断获取当前时间并更新时钟。 首先,程序使用 time() 函数获取当前时间戳,并使用 localtime() 函数将其转换为本地时间。然后,程序使用 sprintf() 函数将时钟字符 串格式化,并使用 print_with_color() 函数将其打印到控制台。接着, 程序使用 Sleep() 函数暂停一秒钟,以便下一次更新时钟。最后,程序 使用 system("cls") 函数清空控制台,以便下一次绘制时钟。 */
- 结果
- 结果
-
制作简易日历
#include <stdio.h> #include <time.h> int main() { time_t t = time(NULL); struct tm *tm = localtime(&t); int year = tm->tm_year + 1900; int month = tm->tm_mon + 1; int day = tm->tm_mday; printf("当前日期:%d年%d月%d日\n", year, month, day); struct tm firstDay; firstDay.tm_year = year - 1900; firstDay.tm_mon = month - 1; firstDay.tm_mday = 1; mktime(&firstDay); int weekday = firstDay.tm_wday; printf("日 一 二 三 四 五 六\n"); for (int i = 0; i < weekday; i++) { printf(" "); } int daysInMonth; switch (month) { case 2: if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) daysInMonth = 29; else daysInMonth = 28; break; case 4: case 6: case 9: case 11: daysInMonth = 30; break; default: daysInMonth = 31; } for (int d = 1; d <= daysInMonth; d++) { if (d == day) { printf("\033[1;31m%2d\033[0m ", d); // 使用红色高亮显示今天的日期 } else { printf("%2d ", d); } if ((weekday + d) % 7 == 0) printf("\n"); } return 0; }
- 结果
- 结果
-
输入日期,计算当前日期是这一年中的第几天(time.h)
(之前发布的一个博客不是用time.h来编写的,这次使用time.h做一个补充)#include <stdio.h> #include <time.h> int main() { // 初始化 int year, month, day; time_t now = time(NULL); struct tm *timeinfo = localtime(&now); // 获取用户输入日期 printf("请输入日期(格式:YYYY-MM-DD):"); scanf("%d-%d-%d", &year, &month, &day); // 更新timeinfo结构体的年月日信息 timeinfo->tm_year = year - 1900; timeinfo->tm_mon = month - 1; timeinfo->tm_mday = day; // 计算并输出这一年中的第几天 int day_of_year = timeinfo->tm_yday + 1; printf("输入日期在这一年中是第 %d 天\n", day_of_year); return 0; }