¿Por qué glibc "timezone" global no está de acuerdo con el tiempo del sistema en DST?
(4)
No creo que la "zona horaria" 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.
Estoy experimentando un problema extraño donde el reloj de mi sistema sabe que es hora de ahorro de luz diurna, pero glibc parece no hacerlo. 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.
La zona horaria correcta actual para mí es Pacific Daylight Time (UTC-7). Cuando le pregunto a mi sistema en qué zona horaria estoy, me dice correctamente:
$ date +%z
-0700
Pero cuando ejecuto el siguiente programa:
#include <time.h>
#include <stdio.h>
int main() {
tzset();
printf("%lu/n", timezone);
return 0;
}
La salida es, incorrectamente:
28800
Lo 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 funciona la zona horaria glibc global.
Las preguntas básicas son entonces:
- ¿Por qué estas dos salidas son diferentes?
- ¿Cómo puedo detectar de manera confiable el desplazamiento UTC del sistema desde un programa C?
Mire el campo tm.tm_isdst después de hacer esto:
time_t current_time;
struct tm tm;
current_time = time(NULL);
localtime_r(¤t_time, &tm);
De acuerdo con la página de manual de localtime_r (3), esto realmente indica si el horario de verano está vigente 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 Australian AEST, espero que funcione para usted.
Puede usar el miembro tm_gmtoff
de struct tm que es igual que :: timezone, pero considera DST y el signo está invertido.
http://www.gnu.org/s/libc/manual/html_node/Time-Zone-Functions.html#Time-Zone-Functions
Aquí está mi código para esto usando tm_gmtoff si se define linux , y usando timezone.tz_minuteswest de gettimofday de lo contrario (aquí ''ltm'' es el resultado de localtime):
{
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);
}