记录:IAR mktime结果不准的问题

现象

项目中需要将日期时间转为时间戳,所以就用了标准库中的mktime来转换。但是测试发现,其结果会偶尔不准,在IAR V8.22 和 V8.32下都有这个问题。V8.22 下是比实际的多一个小时。

解决办法

解决办法也简单,不用标准库就好了。下面是替换mktime的函数

/**
 * @brief Get the Timestamp object
 * 
 * @param ano         - 年
 * @param mes         - 月
 * @param dia         - 日
 * @param hora        - 时
 * @param minuto      - 分
 * @param segundo     - 秒
 * @return uint32_t   - 1970年到当前时间所经过的时长,单位秒
 */
uint32_t getTimestamp(int ano, int mes, int dia, int hora, int minuto, int segundo) {
  //int segundosPorAno = 31557600;
  //long segundosPorAno = 31536000;
  // int segundosPorDia = 86400;

  // Passo 1.
  long anosDesde1970 = ano - 1970;

  // Passo 2.
  long periodosDe400Anos = anosDesde1970 / 400;
  int anoNoPeriodoDe400Anos = anosDesde1970 % 400;

  // Passo 3.
  int periodosDe4AnosNos400 = anoNoPeriodoDe400Anos / 4;
  int anoNoPeriodoDe4Anos = anoNoPeriodoDe400Anos % 4;

  // Passo 4.
  int diasNosAnosAnterioresDoPeriodoDe4Anos = 365 * anoNoPeriodoDe4Anos + (anoNoPeriodoDe4Anos == 3 ? 1 : 0);
  // long segundosPorAno = segundosPorDia * diasNosAnosAnterioresDoPeriodoDe4Anos;
  // Passo 5.
  long diasNoAno = dia - 1;
  int tabelaDeMeses[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  for (int i = 0; i < mes - 1; i++) {
    diasNoAno += tabelaDeMeses[i];
  }

  // Passo 6.
  long dias =
      diasNoAno + diasNosAnosAnterioresDoPeriodoDe4Anos + periodosDe4AnosNos400 * 1461 + periodosDe400Anos * 146097;

  // Passo 7.
  if (anoNoPeriodoDe4Anos == 2 && mes > 2)
    dias++;
  if (anoNoPeriodoDe400Anos > 130 || (anoNoPeriodoDe400Anos == 130 && mes > 2))
    dias--;
  if (anoNoPeriodoDe400Anos > 230 || (anoNoPeriodoDe400Anos == 230 && mes > 2))
    dias--;
  if (anoNoPeriodoDe400Anos > 330 || (anoNoPeriodoDe400Anos == 330 && mes > 2))
    dias--;

  // Passo 8.
  //return segundo + 60 * minuto + 60 * 60 * hora + 60 * 60 * 24 * dias;
  long timeStamp = segundo + 60 * minuto + 60 * 60 * hora + 60 * 60 * 24 * dias;

  //return 60;
  return timeStamp;
}

你可能感兴趣的:(记录:IAR mktime结果不准的问题)