Blog der Heimetli Software AG

Linux: Offset der lokalen Zeit von UTC (GMT) bestimmen

Das tönt einfach, aber es stellt sich bald heraus, dass die Lösung nicht offensichtlich ist.

Als erstes habe ich es trotz den Warnungen in den man-Pages mit gettimeofday probiert, aber immer 0 bekommen.

Auch ein Versuch mit tzset hat nichts gebracht. Eigentlich sollte dieser Aufruf die globale Variable timezone setzen, aber ich bekam nicht den erhofften Wert.

tzset könnte das richtige Resultat liefern wenn die TZ Environment Variable gesetzt ist. Das ist bei mir nicht der Fall. Ich kann mich auch nicht darauf verlassen, dass sie auf dem Zielsystem gesetzt ist und darum habe ich diesen Ansatz nicht weiter untersucht.

Die Lösung: localtime und struct tm

Nach längerem Suchen fand ich die Lösung an einem unerwarteten Ort: struct tm hat unter Linux einen Member namens tm_gmtoff. In diesem steht nach einem Aufruf von localtime der gesuchte Offset !

Dieser Member ist bloss in den Notes zu localtime beschrieben, also nicht gerade offensichtlich.

Wenn man das einmal herausgefunden hat, ist der Code wieder sehr einfach:

/******************************************************************************/
/*                                                                            */
/*                                                           FILE: offset.cpp */
/*                                                                            */
/*    Determines the offset of the local time from UTC                        */
/*    ================================================                        */
/*                                                                            */
/*    V1.00  01-JUN-2013   P. Tellenbach, http://www.heimetli.ch              */
/*                                                                            */
/******************************************************************************/

#include <stdio.h>
#include <time.h>

/**********/
 int main()
/**********/

{
   time_t     now = time( NULL ) ;
   struct tm *pt  = localtime( &now ) ;

   printf( "offset: %ld\n", pt->tm_gmtoff ) ;

   return 0 ;
}