2009-07-23 25 views
6

Necesito convertir el tiempo entre zonas horarias en C (en Linux, por lo que cualquier cosa específica también lo haría).Convertir entre zonas horarias en C

Conozco mi hora actual, local y UTC, tengo el desplazamiento del tiempo objetivo. Estoy tratando de usar mktime, gmtime, localtime y un conjunto similar de funciones, pero todavía no puedo entenderlo.

Gracias de antemano.

Respuesta

5

Como los comentarios no permiten publicar el código, la publicación como una respuesta por separado .. Si conoce el tiempo "local" y "GMT" tiempo, se puede calcular el desplazamiento de la " otro "tiempo" de su hora "local". A continuación, convierta la estructura tm en tiempo calendario, agregue el número de segundos deseado (siendo el desplazamiento del tiempo objetivo) y conviértalo de nuevo a struct tm:

(editado para tener en cuenta otro escenario para usar la normalización de mktime)

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 

int main(int argc, char *argv) { 
    struct timeval tv_utc; 
    struct tm *local_tm, *other_tm; 

    /* 'synthetic' time_t to convert to struct tm for the other time */ 
    time_t other_t_synt; 
    /* Other time is 1 hour ahead of local time */ 
    int other_local_delta = 1*3600; 


    /* the below two lines are just to set local_tm to something */ 
    gettimeofday(&tv_utc, NULL); 
    local_tm = localtime(&tv_utc.tv_sec); 

    printf("Local time: %s", asctime(local_tm)); 

    #ifdef DO_NOT_WRITE_TO_LOCAL_TM 
    other_t_synt = mktime(local_tm) + other_local_delta; 
    #else 
    local_tm->tm_sec += other_local_delta; 
    /* mktime will normalize the seconds to a correct calendar date */ 
    other_t_synt = mktime(local_tm); 
    #endif 

    other_tm = localtime(&other_t_synt); 

    printf("Other time: %s", asctime(other_tm)); 

    exit(0); 
} 
+0

Esto parece estar funcionando bien. Voy a usar local_tm-> tm_sec + = 3600; other_t = mktime (local_tm); en cambio, deje que mktime haga todo lo de normalización para mí. – verma

+0

Sí, eso debería funcionar también - Intenté ser educado y evitar escribir en la memoria de otra persona, ya que la memoria apuntada por local_tm en este ejemplo no pertenece a mi código. –

+0

Eso es un buen punto. – verma

0

De todas maneras, su sistema operativo proporciona algo de soporte para esto.

En sistemas operativos derivados de Unix, es posible que desee consultar las páginas man para asctime, asctime_r, ctime, ctime_r, difftime, gmtime, gmtime_r, localtime, localtime_r, mktime, timegm.

+1

Las API de Posix que mencionas realmente no ofrecen una manera obvia de hacer lo que te pide la pregunta. Las preguntas ya mencionan algunas de estas funciones por nombre, por lo que mencionarlas de nuevo y señalar las páginas man, básicamente, no es una respuesta útil. –

2

Puede usar gmtime() y la estructura tm para establecerlo directamente, siempre que conozca los desplazamientos.

Si conoce su hora local y UTC, conoce su desplazamiento local. Siempre que conozca el desplazamiento del objetivo, solo es cuestión de establecer tm_hour (y, potencialmente, voltear el día, si va al < 0 o> 23).

Para obtener un código de muestra, consulte este gmtime reference page. Muestra compensaciones basadas en offsets de zona horaria.


Editar:

En respuesta a los comentarios - Se puede también dejar que mktime manejar el cambio para usted, que le permite simplificar esto convirtiendo de nuevo a un time_t. Se puede usar algo como:

time_t currentTime; 
tm * ptm; 
time (&currentTime); 
ptm = gmtime (&rawtime); 
ptm->tm_hour += hours_to_shift; 
ptm->tm_minutes += minutes_to_shift; // Handle .5 hr timezones this way 

time_t shiftedTime = mktime(ptm); 
// If you want to go back to a tm structure: 

tm * pShiftedTm = gmtime(&shiftedTime); 
+2

FWIW, no solo tm_hour - p. La hora estándar de la India (IST) es UTC + 5.5 –

+0

Sí, cierto. Tendría que manipular potencialmente casi todos los campos, pero el concepto es sólido. –

+0

En realidad, creo que hay una manera de evitar hacer demasiadas aritméticas manualmente ... ya que los comentarios no permiten el código, lo publicaré como otra respuesta. –

Cuestiones relacionadas