记录一个LUA时间相关的坑

前言

最近在做游戏里的活动配置需求,上线后有一天运营和我说配置的时间没有失效,而在QA时明明测试过功能是正常开启的。
为此我查询了一番log,发现其中的奥秘,并直呼:坑。

事故现场

其实就是一个LUA里的时间转 Unix时间戳的问题,先看以下这段代码:

date = os.time({
     year=2020,month=8,day=31,hour=0,min=0,sec=0})
print(date)
-- 1598803200

然鹅,如果不了解LUA的源码可能就会踩到以下的这个坑:

local date = os.time({
     year=2020,month=8,day=31})
print(date)

拍脑袋一想,这个时间戳肯定和上面的一样啊,结果发现输出的实际上是

-- 1598846400

这个其实是:

date = os.time({
     year=2020,month=8,day=31,hour=12,min=0,sec=0})
print(date)

然后QA的话一般都是下午进行,所以每次配置的时候都是成功的,而在线上的时候一般是早上配置看是否能生效的,所以GG,所幸没有酿成大错。

查看相关的源码我们可以发现在loslib.c中:

static int os_time (lua_State *L) {
     
  time_t t;
  if (lua_isnoneornil(L, 1))  /* called without args? */
    t = time(NULL);  /* get current time */
  else {
     
    struct tm ts;
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_settop(L, 1);  /* make sure table is at the top */
    ts.tm_sec = getfield(L, "sec", 0, 0);
    ts.tm_min = getfield(L, "min", 0, 0);
    ts.tm_hour = getfield(L, "hour", 12, 0);
    ts.tm_mday = getfield(L, "day", -1, 0);
    ts.tm_mon = getfield(L, "month", -1, 1);
    ts.tm_year = getfield(L, "year", -1, 1900);
    ts.tm_isdst = getboolfield(L, "isdst");
    t = mktime(&ts);
    setallfields(L, &ts);  /* update fields with normalized values */
  }
  if (t != (time_t)(l_timet)t || t == (time_t)(-1))
    return luaL_error(L,
                  "time result cannot be represented in this installation");
  l_pushtime(L, t);
  return 1;
}

其中时 为12。

你可能感兴趣的:(lua,lua)