Reputation: 2210
I'm having problems converting a lua date to a timestamp and then obtaining back the original date from it. It does work for non UTC dates, but not with UTC.
Currently my example code is:
local dt1 = os.date( "*t" );
print( dt1.hour );
local dt2 = os.date( "*t", os.time( dt1 ) );
print( dt2.hour );
print( "-=-=-" );
local dt1 = os.date( "!*t" );
print( dt1.hour );
local dt2 = os.date( "!*t", os.time( dt1 ) );
print( dt2.hour );
local dt2 = os.date( "*t", os.time( dt1 ) );
print( dt2.hour );
Which yields the output:
12
12
-=-=-
10
9
11
So, in the second part, after obtaining the timestamp using os.time( os.date( "!*t" ) )
; I don't know how to obtain the original date back. What is it that I'm doing wrong?
Upvotes: 3
Views: 3134
Reputation: 23757
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)
Upvotes: 6
Reputation: 72342
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.
Upvotes: 1
Reputation: 27221
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.
Upvotes: 1