I have CODE as below to calculate offset, Here I executed below code on EST timezone machine whose offset is -18000 seconds i.e. UTC-5.00
Please note I can't use localtime()
due to some limitations which is very long story to mention here.
So I used below logic to do minus of GMT epoch from localtime epoch as below and it returned perfectly the offset.
Now what I want here is suppose case of DST(Day light Saving), where offset will be -14400 seconds i.e. UTC-4.00. Due to +1 adjustment of DST(Day light Saving) for EST time zone.
So will my code mentioned below work? in case system is having DST(Day light Saving). I can not test live right now, as DST(Day light Saving) is not active on my machine.
Its planned as below:
/etc/localtime Sun Mar 14 06:59:59 2021 UT = Sun Mar 14 01:59:59 2021 EST isdst=0 gmtoff=-18000
/etc/localtime Sun Mar 14 07:00:00 2021 UT = Sun Mar 14 03:00:00 2021 EDT isdst=1 gmtoff=-14400
/etc/localtime Sun Nov 7 05:59:59 2021 UT = Sun Nov 7 01:59:59 2021 EDT isdst=1 gmtoff=-14400
/etc/localtime Sun Nov 7 06:00:00 2021 UT = Sun Nov 7 01:00:00 2021 EST isdst=0 gmtoff=-18000
So wanted to know, when DST is active, i.e. say between 14 March 2021 to 7 Nov 2021, will my below code return offset of -14400.
Does time()
function consider epoch time after DST adjustment.
#include <stdio.h>
#include <time.h>
int main ()
{
time_t rawtime, g_epoch, l_epoch;
struct tm * gtm, *ltm;
signed long int offset;
//Get current epoch time
time ( &rawtime );
// convert rawtime epoch to struct tm in GMT
gtm = gmtime ( &rawtime );
// again convert back GMT struct tm to epoch
g_epoch = mktime(gtm);
//convert rawtime epoch to "struct tm* ltm" in local time zone
ltm= localtime(&rawtime);
// again convert back local time zone "struct tm* ltm" to epoch l_epoch
l_epoch= mktime(ltm);
//calculate offset
offset= l_epoch - g_epoch;
printf("Rawtime: %u\n",rawtime);
printf("GMTepoch: %u\n",g_epoch);
printf("Local Epoch: %u\n",l_epoch);
printf("Offset: %ld",offset);
return 0;
}
O/p as below:
Rawtime: 1640176204
GMTepoch: 1640194204
Local Epoch: 1640176204
Offset: -18000
By making this small modification to your program:
gtm = gmtime (&rawtime);
gtm->tm_isdst = -1;
g_epoch = mktime(gtm);
it should work when DST is in effect. Setting tm_isdst
to -1 forces mktime
to decide for itself whether DST is in effect.
You can also skip the manipulations involving ltm
and l_epoch
and the call to localtime
. (I thought the whole point of the exercise was to avoid calling localtime
?) You can compute your offset just fine with
offset = rawtime - g_epoch;
But in the end this is still a pretty dreadful hack, and as @ikegami has pointed out, it won't work properly in the vicinity of DST transitions. For example, the time_t
value 1636261200 properly corresponds to 1am EDT on November 7, 2021, but this code will wrongly determine that it has already fallen back to EST. This problem will be worse (will apply for a larger number of hours) the farther your local time zone is from GMT. There's probably a way around this, but it won't be particularly pretty.