C语言实现字符串格式时间转换时间戳

 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");
}

上一篇:指针这块必须牢牢把握!(初阶-下)


下一篇:Python实现数据透视表