Reputation: 87
So I need to specifically use struct tm to print out my birthday, which I did successfully. However, I am also required to use strftime() to print it in different formats. That's where I encounter my problem, as strftime() only recognizes pointer parameters.
#include <stdio.h>
#include <time.h>
int main(){
struct tm str_bday;
time_t time_bday;
char buffer[15];
str_bday.tm_year = 1994 - 1900 ;
str_bday.tm_mon = 7 - 1;
str_bday.tm_mday = 30;
str_bday.tm_hour = 12;
str_bday.tm_min = 53;
time_bday = mktime(&str_bday);
if(time_bday == (time_t)-1)
fprintf(stdout,"error\n");
else
{
fprintf(stdout,"My birthday in second is: %ld \n",time_bday);
fprintf(stdout,"My birthday is: %s\n", ctime(&time_bday));//Wed July 22 12:53:00 1998
strftime(buffer,15,"%d/%m/%Y",time_bday);
fprintf(stdout,"My birthday in D/M/Y format is %s",buffer);
}
return 0;
}
The errors are:
Error: passing argument 4 of ‘strftime’ makes pointer from integer without a cast
expected ‘const struct tm * restrict’ but argument is of type ‘time_t’
Can someone please tell me how to fix it?
EDIT: Changing time_bday to &str_bday works! But now the program outputs random time and date every time I run it.
EDIT: Instead of fprintf() after strftime(), I used puts(buffer), and it worked perfectly. Also, changing buffer[15] to buffer[30] as I have hours, minutes and seconds.
Upvotes: 4
Views: 6101
Reputation: 153447
mktime(&str_bday);
depends upon the various members1 of struct tm
in its calculation of time_t
.
First initializing members to 0
is good practice.
// struct tm str_bday;
struct tm str_bday = { 0 };
OP's code fails to initialize some members, like tm_sec
, which certainly contribute to an errant result.
Yet it is also important to initialize all relevant members. OP's code does not assign tm_isdst
and with struct tm str_bday = { 0 }
, this is like
str_bday.tm_isdst = 0; // Set time stamp to **standard** time.
The trouble with this is that in OP's school, the daylight time setting for that date is certainly daylight time.
// add
str_bday.tm_isdst = -1; // Let mktime() determine DST setting
// or if one knowns it is daylight time.
str_bday.tm_isdst = 1; // Set time stamp to **daylight** time.
// or if one knowns it is standard time.
str_bday.tm_isdst = 0; // Set time stamp to **standard** time.
The error should be apparent in the printing of ctime(&time_bday)
// My birthday is: Sat Jul 30 13:53:00 1994
My birthday is: Sat Jul 30 12:53:00 1994
Corrected code
#include <locale.h>
#include <time.h>
int main() {
struct tm str_bday = { 0 };
time_t time_bday;
char buffer[15];
str_bday.tm_year = 1994 - 1900;
str_bday.tm_mon = 7 - 1;
str_bday.tm_mday = 30;
str_bday.tm_hour = 12;
str_bday.tm_min = 53;
str_bday.tm_isdst = -1;
time_bday = mktime(&str_bday);
strftime(buffer, sizeof buffer, "%d/%m/%Y", &str_bday);
if (time_bday == (time_t) -1) {
fprintf(stdout, "error\n");
} else {
// Do not assume `long`. Better to cast to a wide type.
fprintf(stdout, "My birthday in second is: %lld \n", (long long) time_bday);
fprintf(stdout, "My birthday is: %s", ctime(&time_bday));
// strftime(buffer,15,"%d/%m/%Y",time_bday);
strftime(buffer, sizeof buffer, "%d/%m/%Y", &str_bday);
fprintf(stdout, "My birthday in D/M/Y format is %s\n", buffer);
}
return 0;
}
1 Members tm_wday
and tm_yday
do not contribute to the calculation, but are updated.
Upvotes: 0
Reputation: 8657
By looking at strftime
's prototype, you can see that you should pass a const struct tm*
as last argument:
size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr);
which would be &str_bday
instead of time_bday
in your case.
struct tm
has a couple of fields you are not initializing and thus take indeterminate values, resulting in the time jumps you're seeing. You can initialize all fields to zero with struct tm str_bday = {0}
, before inserting your values.
Upvotes: 5