Back and forth UTC dates in lua

早过忘川 提交于 2019-12-01 20:53:22

Working with "date tables" in Lua

Let dt be a "date table".
For example, a value returned by os.date("*t") is a "date table".


How to normalize "date table"
For example, after adding 1.5 hours to the current time
local dt = os.date("*t"); dt.min = dt.min + 90
you need to normalize the table fields.

function normalize_date_table(dt)
   return os.date("*t", os.time(dt))
end

This function returns new date table which is equivalent to its argument dt regardless of the meaning of content of dt: whether it contains local or GMT time.


How to convert Unix time to "local date table"

dt = os.date("*t", ux_time)

How to convert Unix time to "GMT date table"

dt = os.date("!*t", ux_time)

How to convert "local date table" to Unix time

ux_time = os.time(dt)

How to convert "GMT date table" to Unix time

-- for this conversion we need precalculated value "zone_diff"
local tmp_time = os.time()
local d1 = os.date("*t",  tmp_time)
local d2 = os.date("!*t", tmp_time)
d1.isdst = false
local zone_diff = os.difftime(os.time(d1), os.time(d2))
-- zone_diff value may be calculated only once (at the beginning of your program)

-- now we can perform the conversion (dt -> ux_time):
dt.sec = dt.sec + zone_diff
ux_time = os.time(dt)

I found the only solution to works this date , time and time zones is to use custom c-build method :

For example, to retrieve string in wanted format, I use this method:

static int idateformat(lua_State *L) {

    time_t t0 = (time_t) lua_tonumber(L,1); 
    const char* ptrn = lua_tostring(L,2);
    const char *tz_value = lua_tostring(L,3);

    int isinenv = 0;
    if(getenv("TZ") != NULL){
        isinenv = 1;
    }
    char old_tz[64];
    if (isinenv == 1) {
        strcpy(old_tz, getenv("TZ"));
    }
    setenv("TZ", tz_value, 1);
    tzset();
    char new_tz[64];
    strcpy(new_tz, getenv("TZ"));


    struct tm *lt = localtime(&t0);
    //"%Y-%m-%d %H:%M:%S"

    char buffer[256];
    strftime(buffer, sizeof(buffer), ptrn, lt);

    if (isinenv == 1) {
        setenv("TZ", old_tz, 1);
        tzset();
    }
    //printf("%ld = %s (TZ=%s)\n", (long)t0, buffer, new_tz);
    lua_pushstring(L, buffer);
    return 1;
} 

Only this way I would suggest.

You're doing nothing wrong.

Lua uses the ISO C and POSIX date and time functions. In particular, os.time uses mktime, which only interprets the input structure according to the current timezone setting in the environment variable TZ. Unfortunately, these standards do not provide a function that interprets the input structure according to GMT/UTC.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!