in reply to Re^6: Standard way to convert timezone in multithreaded script
in thread Standard way to convert timezone in multithreaded script

this XS proved to work:
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> MODULE = tztime PACKAGE = tztime long tz_mktime(sec, min, hour, mday, mon, year, tz_name) int sec int min int hour int mday int mon int year char *tz_name CODE: long epoch; struct tm tz_tm; char *old_tz; const char *tz_p; bool restore = FALSE; tz_tm.tm_sec = sec; tz_tm.tm_min = min; tz_tm.tm_hour = hour; tz_tm.tm_mday = mday; tz_tm.tm_mon = mon; tz_tm.tm_year = year; tz_tm.tm_wday = 0; tz_tm.tm_yday = 0; tz_tm.tm_isdst = -1; tz_p = getenv("TZ"); if(tz_p != NULL) { restore = TRUE; old_tz = malloc(strlen(tz_p) + 1); if(old_tz == NULL) { XSRETURN_UNDEF; } strncpy(old_tz,tz_p,strlen(tz_p) + 1); } setenv("TZ",tz_name,1); tzset(); epoch = (long)mktime(&tz_tm); if(restore) { putenv(old_tz); free(old_tz); } else { unsetenv("TZ"); } tzset(); RETVAL = epoch; OUTPUT: RETVAL void tz_gettime(epoch, tz_name) long epoch char *tz_name; PPCODE: struct tm tz_tm; char *old_tz; const char *tz_p; bool restore = FALSE; tz_p = getenv("TZ"); if(tz_p != NULL) { restore = TRUE; old_tz = malloc(strlen(tz_p) + 1); if(old_tz == NULL) { XPUSHs(sv_2mortal(newSVnv(errno))); } strncpy(old_tz,tz_p,strlen(tz_p) + 1); } setenv("TZ",tz_name,1); tzset(); localtime_r(&epoch,&tz_tm); if(restore) { putenv(old_tz); free(old_tz); } else { unsetenv("TZ"); } tzset(); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_sec))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_min))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_hour))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_mday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_mon))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_year))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_wday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_yday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_isdst)));