学习C – C日期和时间函数
time.h标头声明产生时间和日期的函数。
获取时间值
返回时间值的最简单的函数具有以下原型:
clock_t clock(void);
这个函数返回一些参考点后的处理器时间。
在程序中的某些进程的开始和结束处,调用clock()函数。
返回值的类型为clock_t,它是在time.h中定义的整数类型。
clock()函数返回的值以时钟刻度来度量。
要将此值转换为秒,请将其除以由time.h中定义的宏CLOCKS_PER_SEC生成的值。
如果发生错误,clock()函数返回-1。
time()函数返回日历时间作为类型为time_t的值。
日历时间是当前时间,通常以特定日期的固定时间为单位,以秒为单位。
固定的时间和日期通常是1970年1月1日00:00:00 GMT,这是时间值的定义的典型。
time()函数的原型是:
time_t time(time_t *timer);
如果参数不为NULL,则当前日历时间也存储在定时器中。
类型time_t在头文件中定义,通常等同于long类型。
要计算time()返回的两个连续time_t值之间的经过时间(秒),可以使用具有此原型的difftime()函数:
double difftime(time_t T2, time_t T1);
该函数将以秒为单位的T2 – T1值返回double类型的值。
该值是在产生time_t值T1和T2的两个time()函数调用之间经过的时间。
例子
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
int main(void) {
time_t calendar_start = time(NULL); // Initial calendar time
clock_t cpu_start = clock(); // Initial processor time
int count = 0; // Count of number of loops
const long long iterations = 1000000000LL; // Loop iterations
char answer = "y";
double x = 0.0;
printf("Initial clock time = %lld Initial calendar time = %lld\n",
(long long)cpu_start, (long long)calendar_start);
while(tolower(answer) == "y") {
for(long long i = 0LL ; i < iterations ; ++i)
x = sqrt(3.14159265);
printf("%lld square roots completed.\n", iterations*(++count));
printf("Do you want to run some more(y or n)? \n");
scanf("\n%c", &answer, sizeof(answer));
}
clock_t cpu_end = clock(); // Final cpu time
time_t calendar_end = time(NULL); // Final calendar time
printf("Final clock time = %lld Final calendar time = %lld\n",
(long long)cpu_end, (long long)calendar_end);
printf("CPU time for %lld iterations is %.2lf seconds\n",
count*iterations, ((double)(cpu_end-cpu_start))/CLOCKS_PER_SEC);
printf("Elapsed calendar time to execute the program is %8.2lf seconds.\n",
difftime(calendar_end, calendar_start));
return 0;
}
上面的代码生成以下结果。
获取日期
要将今天的日期作为字符串,请使用具有此原型的函数ctime():
char *ctime(const time_t *timer);
该函数接受一个指向time_t变量的指针,作为包含由time()函数返回的日历时间值的参数。
它返回一个指向包含日期,日期,时间和年份的26个字符的字符串的指针,它由换行符’\ 0’终止。
返回的典型字符串可能如下所示:
"Mon Aug 21 11:45:56 2015\n\0"
ctime()函数不知道分配用于存储结果的字符串长度。
有一个可选的更安全的版本的功能有这个原型:
errno_t ctime_s(char * str, rsize_t size, const time_t *timer);
您可以使用ctime_s()函数,如下所示:
char time_str[30] = {"\0"}; time_t calendar = time(NULL); if(!ctime_s(time_str, sizeof(time_str), &calendar)) printf_s("%s", time_str); else fprintf_s(stderr, "Error converting time_t value\n");
我们可以通过使用localtime()函数从日历时间值获取时间和日期的各个组件。这有原型:
struct tm *localtime(const time_t *timer);
此函数接受一个指向time_t值的指针,并返回一个指向tm类型的指针,该结构在time.h中定义。
如果定时器无法转换,则返回NULL。
可选版本有原型:
struct tm *localtime_s(const time_t * restrict timer, struct tm * restrict result);
两个参数必须为non_NULL。
该结构至少包含下表中列出的成员。
成员 | 描述 |
---|---|
tm_sec | 秒(0到60)在24小时制的分钟后。该值对于闰秒支持达到60。 |
tm_min | 24小时制的小时分钟后(0到59) |
tm_hour | 24小时制的小时(0到23) |
tm_mday | 一月中的第几天(1到31) |
tm_mon | 月份(0至11) |
tm_year | 年份(本年减去1900年) |
tm_wday | 一周的第几天(星期日为0;星期六为6) |
tm_yday | 一年中的第几天(0到365) |
tm_isdst | 夏令时标志。正为夏令时间,0不为夏令时,负为不知道。 |
所有的成员都是int类型。
这是一个代码片段,将从tm结构的成员输出日期和日期:
time_t calendar = time(NULL); // Current calendar time struct tm time_data; const char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; const char *months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; if(localtime_s(&calendar, &time_data)) printf_s("Today is %s %s %d %d\n", days[time_data.tm_wday], months[time_data.tm_mon], time_data.tm_mday, time_data.tm_year+1900);
asctime()及其可选的更安全的伙伴asctime_s()生成一个tm结构的字符串表示形式。
它们的原型是:
char *asctime(const struct tm *time_data); errno_t asctime_s(char *str, rsize_t size, const struct tm *time_data);
asctime_s()将字符串存储在str中,它必须是至少有26个元素的数组; size是str中元素的数量。
成功时,该函数返回0,失败时返回非零整数。
该函数适用于年均1000到9999的tm结构。
结果的字符串与ctime()生成的字符串格式相同。
#include <stdio.h>
#include <time.h>
int main(void)
{
const char *day[7] = {
"Sunday" , "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
const char *month[12] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
const char *suffix[] = { "st", "nd", "rd", "th" };
enum sufindex { st, nd, rd, th } sufsel = th; // Suffix selector
struct tm ourT; // The time structure
time_t tVal = time(NULL); // Calendar time
if(!localtime_s(&tVal, &ourT)) // Populate time structure
{
fprintf(stderr, "Failed to populate tm struct.\n");
return -1;
}
switch(ourT.tm_mday)
{
case 1: case 21: case 31:
sufsel= st;
break;
case 2: case 22:
sufsel= nd;
break;
case 3: case 23:
sufsel= rd;
break;
default:
sufsel= th;
break;
}
printf("Today is %s the %d%s %s %d. ",
day[ourT.tm_wday],
ourT.tm_mday,
suffix[sufsel],
month[ourT.tm_mon],
1900 + ourT.tm_year);
printf("The time is %d : %d : %d.\n",
ourT.tm_hour, ourT.tm_min, ourT.tm_sec );
return 0;
}
上面的代码生成以下结果。
获取日期的星期几
您可以使用mktime()函数确定给定日期的星期几。
该函数具有原型:
time_t mktime(struct tm *ptime);
#include <stdio.h>
#include <time.h>
int main(void)
{
const char *day[7] = {
"Sunday" , "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
const char *month[12] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
const char *suffix[] = { "st", "nd", "rd", "th" };
enum sufindex { st, nd, rd, th } sufsel = th; // Suffix selector
struct tm birthday = {0}; // A birthday time structure
char name[30] = {"C"};
printf("Enter the birthday as day month year integers separated by spaces."
"\ne.g. Enter 1st February 1985 as 1 2 1985 : ");
scanf(" %d %d %d", &birthday.tm_mday, &birthday.tm_mon, &birthday.tm_year);
birthday.tm_mon -= 1; // Month zero-based
birthday.tm_year -= 1900; // Year relative to 1900
if(mktime(&birthday) == - 1)
{
fprintf_s(stderr, "Operation failed.\n");
return -1;
}
switch(birthday.tm_mday)
{
case 1: case 21: case 31:
sufsel= st;
break;
case 2: case 22:
sufsel= nd;
break;
case 3: case 23:
sufsel= rd;
break;
default:
sufsel= th;
break;
}
printf("born on the %d%s %s %d, which was a %s.\n",
birthday.tm_mday, suffix[sufsel], month[birthday.tm_mon],
1900 + birthday.tm_year, day[birthday.tm_wday]);
return 0;
}
上面的代码生成以下结果。