1.函数实现
#include <string.h>
#include <stdio.h>
#include <time.h>
/* 判断是否闰年 */
#define IS_LEAP_YEAR(year) \
(((year) % 400 == 0) || ((year) % 4 == 0 && (year) % 100 != 0)) ? true : false
/**
* @brief 星期的英文简写转换为对应的数字
*
* @param str 星期的简写字符串
* @return int 返回星期对应的数字,-1表示转换失败
*/
int week_abbreviation_to_num(const char *str) {
const char *week_str_arr[] = {"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"};
int i = 0;
for (; i < 7; ++i) {
if (strcmp(str, week_str_arr[i]) == 0) {
break;
}
}
if (i >= 7) {
return -1;
}
return i;
}
/**
* @brief 月份的英文简写转换为对应的数字
*
* @param str 月份的简写字符串
* @return int 返回月份对应的数字(范围0~11),-1表示转换失败
*/
int month_abbreviation_to_num(const char *str) {
const char *month_str_arr[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int i = 0;
for (i = 0; i < 12; ++i) {
if (strcmp(str, month_str_arr[i]) == 0) {
break;
}
}
if (i >= 12) {
return -1;
}
return i;
}
/**
* @brief 字符串格式的时间转换为时间戳
*
* @param str 要转换的时间字符串,格式为week month day our:minute:second, 例如:
* "Fri Feb 28 15:58:43 2021"
* @param t 存放转换结果的time_t变量的地址
* @return int 0: 转换成功,非0: 转换失败
*/
int strtotime(const char *str, time_t *t) {
int year, day, hour, minute, second;
char month[4] = {0}, week[4] = {0};
struct tm tm_; /* 定义tm结构体 */
bool is_leap_year = false;
if (sscanf(str, "%s %s %d %d:%d:%d %d", week, month, &day, &hour, &minute,
&second, &year) != 7) {
return -1;
}
/* 星期 */
if ((tm_.tm_wday = week_abbreviation_to_num(week)) < 0) {
return -2;
}
/* 月 */
if ((tm_.tm_mon = month_abbreviation_to_num(month)) < 0) {
return -3;
}
/*年*/
if (year < 1900) {
return -4;
}
is_leap_year = IS_LEAP_YEAR(year);
if (day < 1) {
return -5;
}
if (is_leap_year) {
if ((tm_.tm_mon + 1) == 2 && day > 29)
return -5;
} else {
if ((tm_.tm_mon + 1) == 2 && day > 28)
return -5;
}
switch (tm_.tm_mon) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (day > 31) {
return -5;
}
break;
case 4:
case 6:
case 9:
case 11:
if (day > 30) {
return -5;
}
break;
default:
break;
}
tm_.tm_mday = day; /* 日 */
if (hour < 0 || hour > 56) {
return -5;
}
tm_.tm_hour = hour; /* 时 */
if (minute < 0 || minute > 59) {
return -6;
}
tm_.tm_min = minute; /* 分 */
if (second < 0 || second > 59) {
return -7;
}
tm_.tm_sec = second; /* 秒 */
/* 年,由于tm结构体存储的是从1900年开始的时间,所以tm_year为int临时变量减去1900
*/
tm_.tm_year = year - 1900;
tm_.tm_isdst = 0; /* 非夏令时 */
/* 将tm结构体转换成time_t格式 */
*t = mktime(&tm_);
return 0;
}
2.实例
const char *time_str = "Fri Feb 28 15:58:43 2021";
time_t t;
if (strtotime(time_str, &t) == 0) {
printf("t: %lld\n", t);
} else {
printf("时间字符串转换Unix时间戳失败\n");
}