Comment faire pour convertir de l'heure UTC en heure locale en C?

C'est une question simple, mais la solution semble être loin d'être simple. Je voudrais savoir comment faire pour convertir de l'heure UTC en heure locale. Je suis à la recherche d'une solution dans C, de série et de plus ou moins garanti pour fonctionner sur n'importe quel ordinateur à n'importe quel endroit.

J'ai lu les liens suivants attentivement, mais je ne peux pas y trouver une solution:

La conversion de chaîne de caractères contenant localtime en UTC, dans C

La conversion Entre l'heure Locale et l'heure GMT/UTC en C/C++

J'ai essayé un certain nombre de variations, telles que (datetime est une chaîne avec la date et l'heure UTC):

strptime(datetime, "%A %B %d %Y %H %M %S", tp);
strftime(printtime, strlen(datetime), "%A %B %d %Y %H %M %S", tp);

Ou

strptime(datetime, "%A %B %d %Y %H %M %S", tp);
lt=mktime(tp);
printtime=ctime(&lt);

Peu importe ce que j'essaie printtime finit par être le même que l'UTC.

Modifier 11-29-2013: basé sur le très utile de répondre par "R" ci-dessous j'ai enfin réussi à créer un exemple de travail. Je l'ai trouvé de travail correct dans les deux fuseaux horaires je l'ai testé, HEC et PST:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
long long diff_tm(struct tm *a, struct tm *b)
{
return a->tm_sec - b->tm_sec
+60LL*(a->tm_min - b->tm_min)
+3600LL*(a->tm_hour - b->tm_hour)
+86400LL*(a->tm_yday - b->tm_yday)
+(a->tm_year-70)*31536000LL
-(a->tm_year-69)/4*86400LL
+(a->tm_year-1)/100*86400LL
-(a->tm_year+299)/400*86400LL
-(b->tm_year-70)*31536000LL
+(b->tm_year-69)/4*86400LL
-(b->tm_year-1)/100*86400LL
+(b->tm_year+299)/400*86400LL;
}
int main()
{
time_t utc, local;
char buf[100];
const char datetime[]="2013 11 30 23 30 26 UTC"; /* hard coded date and time in UTC */
struct tm *tp=malloc(sizeof(struct tm));
if(tp==NULL)
exit(-1);
struct tm *localt=malloc(sizeof(struct tm));
if(localt==NULL)
exit(-1);
memset(tp, 0, sizeof(struct tm));
memset(localt, 0, sizeof(struct tm));
printf("UTC date and time to be converted in local time: %s\n", datetime);
/* put values of datetime into time structure *tp */
strptime(datetime, "%Y %m %d %H %M %S %z", tp);
/* get seconds since EPOCH for this time */
utc=mktime(tp);
printf("UTC date and time in seconds since EPOCH: %d\n", utc);
/* lets convert this UTC date and time to local date and time */
struct tm e0={ .tm_year = 70, .tm_mday = 1 }, e1, new;
/* get time_t EPOCH value for e0 (Jan. 1, 1970) */
time_t pseudo=mktime(&e0);
/* get gmtime for this value */
e1=*gmtime(&pseudo);
/* calculate local time in seconds since EPOCH */
e0.tm_sec += utc - diff_tm(&e1, &e0);
/* assign to local, this can all can be coded shorter but I attempted to increase clarity */
local=e0.tm_sec;
printf("local date and time in seconds since EPOCH: %d\n", local);
/* convert seconds since EPOCH for local time into localt time structure */
localt=localtime(&local);
/* get nicely formatted human readable time */
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S %Z", localt);
printf("local date and time: %s\n", buf);
}

Il devrait compiler sans problème sur la plupart des systèmes. J'ai codé en dur date et de l'heure en UTC qui seront ensuite convertis à la date et l'heure locale.

Peut-on supposer POSIX (puisque vous utilisez strptime) ou tout simplement C?
Désolé manqué que, oui, vous pouvez supposer POSIX.

OriginalL'auteur aseq | 2012-01-31