This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Questions about strptime()/strftime()
- From: Richard Harvey Chapman <hchapman-libc-alpha at 3gfp dot com>
- To: libc-help at sourceware dot org
- Date: Tue, 01 Jul 2008 15:04:21 -0400
- Subject: Re: Questions about strptime()/strftime()
- References: <485D4113.9050107@3gfp.com> <119aab440806211122m3374fcd7k4df57496b11a5aef@mail.gmail.com>
Carlos O'Donell wrote:
This returns "Illegal seek" because "%F", "%z", and "%Z" are not valid
formats which strptime can convert.
Thanks for the tip. I didn't realize that strptime() does not support
all of the formats that strftime() does.
To reiterate my goal, I would like to be able to get the time from one
machine and use that to set the time on another machine. I would further
like it if I could first convert that time to a nice human readable
format and then have the destination machine convert it back.
In decreasing order of preference ( time_t ==> string ==> time_t ):
1. 1214933436 ==> "13:30:36 2008-07-01 -0400 EDT" ==> 1214933436
2. 1214933436 ==> "17:30:36 2008-07-01 -0500 UTC" ==> 1214933436
3. 1214933436 ==> "17:30:36 2008-07-01" ==> 1214933436
4. 1214933436 ==> "1214933436" ==> 1214933436
I'm currently trying to get #3 to work. However, mktime() always seems
to impose a timezone (not of my choosing) on its output. I've revised my
test program to illustrate the problem. The code is appended below along
with output, linux version, and glibc version.
Thanks,
R.
======================
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
void test_mktime(void);
void printTimeOk(struct tm *t, time_t t2);
int main()
{
test_mktime();
return(0);
}
void printTimeOk(struct tm *t, time_t t2)
{
time_t result = (uintmax_t)mktime(t);
//printf("\t\t");
if ((uintmax_t)result - t2 != 0)
{
printf("ERROR: old(%ju) - new(%ju) = %ju\n",
(uintmax_t)result,
(uintmax_t)t2,
((uintmax_t)result - t2));
}
else
{
printf("OK\n");
}
}
void test_mktime (void)
{
char str[100];
char *result = NULL;
time_t t;
struct tm tt_r;
//char format[] = "%T %F"; // time, date // "15:02:18 2008-06-20"
char format[] = "%H:%M:%S %Y-%m-%d"; // time, date // "15:02:18 2008-06-20"
int len = 0;
char *tz;
char zone[100];
// Get current time in seconds
t = time(NULL);
// Get the timezone (if set)
tz = getenv("TZ");
if (tz == NULL)
{
strcpy(zone, "(not set)");
}
else
{
strcpy(zone, tz);
}
// Print it
printf("\n");
printf("Local: %sGM: %s%ju secs since the Epoch\n",
asctime(localtime(&t)),
asctime(gmtime(&t)),
(uintmax_t)t);
printf("Time zone = \"%s\"\n", zone);
printf("\n");
// Now convert it to a string using gmtime()
len = strftime(str, 100, format, gmtime(&t));
if (0 == len) { printf("Fail at line: %d\n", __LINE__); return; }
printf(" Time now is \"%s\" (GM)\n", str);
printf("\n");
// Now convert back to a tm struct and print
memset(&tt_r, 0, sizeof(tt_r));
result = strptime(str, format, &tt_r);
if (NULL == result) { printf("Fail at line: %d\n", __LINE__); return; }
printf("Reverse time is \"%02u:%02u:%02u %4u-%02u-%02u %05ld %s %s(%d)\"
(GM)\n",
tt_r.tm_hour,
tt_r.tm_min,
tt_r.tm_sec,
tt_r.tm_year + 1900,
tt_r.tm_mon + 1,
tt_r.tm_mday,
tt_r.tm_gmtoff / 36,
tt_r.tm_zone == NULL ? "(null)" : tt_r.tm_zone,
tt_r.tm_isdst ? "DST" : "",
tt_r.tm_isdst);
printTimeOk(&tt_r, t);
// Try setting a timezone to see if the result changes
//setenv("TZ", "GMT0", 1);
printf("\nSetting TZ to \"UTC\"\n");
setenv("TZ", "UTC", 1);
tzset();
//tt_r.tm_isdst = 1;
printTimeOk(&tt_r, t);
}
======================
dev1:~# uname -a
Linux dev1 2.6.18harvey #2 SMP Thu Jul 26 03:05:21 EDT 2007 i686 GNU/Linux
dev1:~# ls -l /lib/libc-*.so
-rwxr-xr-x 1 root root 1147548 2007-07-30 16:41 /lib/libc-2.3.6.so
dev1:~# gcc time_formats_3.c
time_formats_3.c: In function ÃÂÂtest_mktimeÃÂÂ:
time_formats_3.c:83: warning: assignment makes pointer from integer
without a cast
dev1:~# ./a.out
Local: Tue Jul 1 14:34:07 2008
GM: Tue Jul 1 14:34:07 2008
1214937247 secs since the Epoch
Time zone = "(not set)"
Time now is "18:34:07 2008-07-01" (GM)
Reverse time is "18:34:07 2008-07-01 00000 (null) (0)" (GM)
ERROR: old(1214955247) - new(1214937247) = 18000
Setting TZ to "UTC"
ERROR: old(1214940847) - new(1214937247) = 3600
dev1:~#
======================