2009-03-11 13 views
6

Tengo un problema extraño en el que el reloj de mi sistema sabe que es hora de ahorro de luz diurna, pero glibc parece no tenerlo. Esta es una instalación actualizada de Ubuntu, y he comprobado/etc/localtime y tiene el tiempo de cambio correcto para el cambio a DST de la semana pasada.¿Por qué glibc "timezone" global no está de acuerdo con el tiempo del sistema en DST?

La zona horaria correcta actual para mí es Pacific Daylight Time (UTC-7). Cuando le pregunto a mi sistema en que zona horaria en que estoy, me dice correctamente:

$ date +%z 
-0700 

Pero cuando corro el siguiente programa:

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

int main() { 
    tzset(); 
    printf("%lu\n", timezone); 
    return 0; 
} 

La salida es, de forma incorrecta:

28800 

que corresponde a UTC-8, o hora estándar del Pacífico. (Y no, TZ no está configurado en mi entorno)

Pensé que glibc y el programa de fecha obtendrían su información de zona horaria de la misma fuente, pero aparentemente no lo hacen o no entiendo cómo la zona horaria glibc trabajos globales.

Las preguntas básicas son entonces:

  1. ¿Por qué estos dos salidas diferentes
  2. ¿Cómo puedo detectar de manera fiable el sistema de desplazamiento desde un programa en C UTC?

Respuesta

3

No creo que "timezone" cambie con el horario de verano. Pruebe la variable "luz del día". En mi sistema:

 
     The external variable timezone contains the difference, in seconds, 
     between UTC and local standard time (for example, in the U.S. Eastern 
     time zone (EST), timezone is 5*60*60). The external variable daylight 
     is non-zero only if a summer time zone adjustment is specified in the 
     TZ environment variable. 
+0

Mi lectura de la página de manual para tzset indica que la variable dayllight solo indica si la zona local usa el horario de verano en algún momento, y no necesariamente indica si está vigente actualmente. –

+0

Creo que estoy de acuerdo contigo. Sugeriría {time_t t = time (NULL); printf ("% d \ n", (int) difftime (mktime (gmtime (& t)), t)); } pero eso me da el mismo resultado que "zona horaria". –

1

Mira campo tm.tm_isdst después de hacer esto:

time_t current_time; 
    struct tm tm; 

    current_time = time(NULL); 
    localtime_r(&current_time, &tm); 

De acuerdo con la localtime_r (3) página de manual, esto en realidad indicar si el horario de verano está en vigor en el momento especificado . Creo que debes asumir que DST agrega una hora a la variable de la zona horaria (3) que ya estás utilizando, o hacer el truco contra GMT.

Funciona para mí en Australia AEST, espero que funcione para usted.

0

Aquí está mi código para esta usando tm_gmtoff si se define Linux, y el uso de timezone.tz_minuteswest gettimofday lo contrario (en este caso 'LTM' es la salida de hora local):

{ 
    int tz_offset; 

#if defined(__linux__) 
    tz_offset= ltm.tm_gmtoff; 
#else 
    tz_offset= -tz.tz_minuteswest*60 + ltm.tm_isdst*3600; 
#endif 

    printf ("LT = UTC +d sec\n", tz_offset); 
} 
Cuestiones relacionadas