什么是localtime函数的有效参数?

时间:2016-01-27 21:35:35

标签: c

我这里有一个使用localtime函数的代码。但是对于其输入参数的某些值,代码崩溃(返回空指针)。我想知道其输入的允许范围。

#include <stdio.h>
#include <time.h>

int main ()
{
  time_t rawtime;
  struct tm g;
  struct tm *gp;
  __int64 tim;

  tim = 7476811632013133299LL; // I know it's a weird number but valid for time_t
  rawtime = tim / 1000LL;
  gp = localtime(&rawtime);
  printf("Pointer gp = %p\n", gp);

  g = *gp; // this crahses because gp = NULL

  return 0;
}

那么可以说关于本地时间函数的允许输入范围呢?

3 个答案:

答案 0 :(得分:5)

C标准未规定允许范围。

引用N1570草稿:

  

localtime 函数返回指向细分的指针   time,如果指定的时间无法转换为空指针   当地时间。

在尝试取消引用之前,您应该检查结果是否为NULL

答案 1 :(得分:3)

来自MSDN page for localtime

  

返回指向结构结果的指针,如果日期通过则返回NULL   功能是:

     
      
  • 1970年1月1日午夜之前。

  •   
  • 在2038年1月19日03:14:07之后,UTC(使用_time32和time32_t)。

  •   
  • 在12月31日23:59:59之后,UTC(使用_time64和__time64_t)。

  •   

答案 2 :(得分:3)

为了好玩,我让我的编译器尝试推断结果:

#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

bool Valid_time_t(time_t t) {
  struct tm *gp;
  gp = gmtime(&t);
  return gp != NULL;
}

time_t MaxValid_time_t(void) {
  time_t mn, mx, dt;
  time(&mn);
  do {
    time(&mx);
  } while (mx == mn);
  dt = mx - mn;
  for (;;) {
    time_t mx2 = mx + dt;   // Technically a problem as int overflow is UB
    if (mx2 <= mx) break;
    mx = mx2;
    //printf("mx %jd\n", (intmax_t) mx);
    dt *= 2;
  }
  while (dt) {
    dt /= 2;
    time_t mx2 = mx + dt;   // Technically a problem as int overflow is UB
    if (mx2 > mx) mx = mx2;
    //printf("mx_ %jd\n", (intmax_t) mx);
  }

  time_t mid;
  while (mn < mx) {
    mid = mx / 2 + mn / 2 + (mx % 2 + mn % 2) / 2;
    if (Valid_time_t(mid)) {
      mn = mid + 1;
    } else mx = mid - 1;
    // printf("3 %jd %jd %jd\n", (intmax_t) mn, (intmax_t) mid, (intmax_t) mx);
  }

  printf("%jd\n", (intmax_t) mn);
  printf("%s\n", asctime(gmtime(&mn)));
  return mn;
}

int main(void) {
  return (int) MaxValid_time_t();
}

输出gcc cygwin

2147483647
Tue Jan 19 03:14:07 2038

gmtime()中使用Valid_time_t()输出MS VS 2010。 (好奇地在localtime()使用Valid_time_t()后的13个小时。localtime()的上限似乎与gmtime()不同。

32535291599
Thu Jan 01 20:59:59 3001

localtime()中使用Valid_time_t()时OP的输出。

32535244800

YMMV