Reputation: 197
After closely looking at time.h more than a few times I wrote the following func :
void output_date ( int day, int month, int year ) {
char buffer[64] = "";
struct tm *e_time = calloc( (size_t) 1, sizeof(struct tm) );
e_time->tm_year = year - 1900;
e_time->tm_mon = month - 1;
e_time->tm_mday = day;
e_time->tm_hour = 0;
e_time->tm_min = 0;
e_time->tm_sec = 0;
e_time->tm_isdst = -1;
/* strftime ( buffer, 64, (char *)0, e_time ); */
strftime ( buffer, 64, "%a %b %e %H:%M:%S %Z (%z) %Y", e_time );
printf ( "%s\n", buffer );
free(e_time);
e_time = NULL;
}
I then called this function with a range of possible inputs and saw nothing but bizarre output like so :
Sun Jul 8 00:00:00 () 2013
Sun Jul 9 00:00:00 () 2013
Sun Jul 10 00:00:00 () 2013
Sun Jul 11 00:00:00 () 2013
Sun Jul 12 00:00:00 () 2013
When I test my format string to strftime I see good results thus :
$ date -u "+%a %b %e %H:%M:%S %Z (%z) %Y"
Sat Oct 12 00:40:05 GMT (+0000) 2013
I even went so far as to single step via a debugger and saw the same bizarre results :
stopped in main at line 27 in file "flight.c"
27 output_date ( day+1, month+1, year );
(dbx) print day+1, month+1, year
day+1 = 1
month+1 = 1
year = 1977
(dbx) step
stopped in output_date at line 43 in file "flight.c"
43 char buffer[64] = "";
(dbx) step
stopped in output_date at line 44 in file "flight.c"
44 struct tm *e_time = calloc( (size_t) 1, sizeof(struct tm) );
(dbx) step
stopped in output_date at line 46 in file "flight.c"
46 e_time->tm_year = year - 1900;
(dbx) print e_time
e_time = 0x100101640
(dbx) step
stopped in output_date at line 47 in file "flight.c"
47 e_time->tm_mon = month - 1;
(dbx) step
stopped in output_date at line 48 in file "flight.c"
48 e_time->tm_mday = day;
(dbx) step
stopped in output_date at line 49 in file "flight.c"
49 e_time->tm_hour = 0;
(dbx) step
stopped in output_date at line 50 in file "flight.c"
50 e_time->tm_min = 0;
(dbx) step
stopped in output_date at line 51 in file "flight.c"
51 e_time->tm_sec = 0;
(dbx) step
stopped in output_date at line 52 in file "flight.c"
52 e_time->tm_isdst = -1;
(dbx) step
stopped in output_date at line 55 in file "flight.c"
55 strftime ( buffer, 64, "%a %b %e %H:%M:%S %Z (%z) %Y", e_time );
(dbx) print *e_time
*e_time = {
tm_sec = 0
tm_min = 0
tm_hour = 0
tm_mday = 1
tm_mon = 0
tm_year = 77
tm_wday = 0
tm_yday = 0
tm_isdst = -1
}
(dbx) step
stopped in output_date at line 57 in file "flight.c"
57 printf ( "%s\n", buffer );
(dbx) print buffer
buffer = "Sun Jan 1 00:00:00 () 1977"
(dbx) quit
In fact, all I ever get is a day of the week being Sunday and the correct month with the correct day and year. Not much else seems correct.
Am I missing something obvious ?
Upvotes: 1
Views: 339
Reputation: 122383
You gave the field tm_isdst
the value of -1
, which means the daylight saving time is not available, change it to 1
if the daylight saving time is in effect, or 0
if it's not.
As @Paul Griffiths points out, calling mktime(e_time)
is the better option here, the mktime
function will fill the broken down e_time
, as it will fix the fileds like tm_wday
and tm_day
as well. For the field of tm_isdst
, it follows this rule:
a positive or zero value for
tm_isdst
causes themktime
function to presume initially that Daylight Saving Time, respectively, is or is not in effect for the specified time. A negative value causes it to attempt to determine whether Daylight Saving Time is in effect for the specified time.
Upvotes: 1
Reputation: 25908
You should call mktime(e_time)
after populating your struct, but before calling strftime()
. You have some other struct members that are not currently being completed. Passing a struct with uninitialized values (or initialized to incorrect values, here, due to your calloc()
call) is generally a Bad Thing to do, and mktime()
modifies the struct you pass to fill them in for you.
Like so:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void output_date ( int day, int month, int year ) {
char buffer[64] = "";
struct tm *e_time = calloc( (size_t) 1, sizeof(struct tm) );
e_time->tm_year = year - 1900;
e_time->tm_mon = month - 1;
e_time->tm_mday = day;
e_time->tm_hour = 0;
e_time->tm_min = 0;
e_time->tm_sec = 0;
e_time->tm_isdst = -1;
if ( mktime(e_time) < 0 ) {
fprintf(stderr, "Error getting calendar time.\n");
exit(EXIT_FAILURE);
}
int n = strftime ( buffer, 64, "%a %b %e %H:%M:%S %Z (%z) %Y", e_time );
printf("Return from strftime() is %d\n", n);
printf ( "%s\n", buffer );
free(e_time);
e_time = NULL;
}
int main(void) {
output_date(12, 6, 2013);
return 0;
}
yields:
paul@local:~/src/c/scratch$ ./st
Return from strftime() is 36
Wed Jun 12 00:00:00 EDT (-0400) 2013
paul@local:~/src/c/scratch$
Upvotes: 1