Reputation: 33
I'm working on a function where I get parameters from users, find out what is the first day from that week and then print out the whole week to user.
This is what I've done so far:
#include <time.h>
#include <stdio.h>
void week(int day, int month, int year)
{
struct tm time;
char buffer[80];
int i;
time.tm_year = year - 1900;
time.tm_mon = month - 1;
time.tm_mday = day;
time_t rightTime = mktime(&time);
time.tm_wday = rightTime;
time.tm_wday = mktime(&time);
for (i = 0; i < 7; i++)
{
strftime(buffer, sizeof(buffer), "%A %d. %B %Y\n",&time);
printf(buffer);
time.tm_mday = time.tm_mday + 1;
time.tm_wday = time.tm_wday + 1;
}
}
Then I started to experiment with code to get first day of the week. I tried to get first day of the week by identifying which weekday it is and then minus all the days until the date is Monday. Then I can start print the whole week to user from Monday till Sunday. Example if wday is saturday(6):
if(rightTime == 6)
{
time.tm_mday = time.tm_mday - 6;
}
time.tm_wday = mktime(&time);
It still doesn't feel the right way but I cant figure out how to find out the first day of that given week, refresh all the information and then print it out for user.
Right output if parameters for day, month and year would be for example 20 4 2017:
Monday 17. April 2017
Tuesday 18. April 2017
Wednesday 19. April 2017
Thursday 20. April 2017
Friday 21. April 2017
Saturday 22. April 2017
Sunday 23. April 2017
All help is appreciated!
Upvotes: 2
Views: 447
Reputation: 153498
mktime()
uses many of the members in struct tm
, so calling mktime()
without setting those members results in undefined behavior (UB).
// struct tm time;
struct tm time = { 0 }; // set all fields to 0.
...
time.tm_year = year - 1900;
time.tm_mon = month - 1;
time.tm_mday = day;
time_t rightTime = mktime(&time);
After mktime()
, the day-of-the-week member is set.
int days_since_Sunday = time.tm_wday; // 0 - 6
... how to find out the first day of that given week, refresh all the information and then print it out for user. ... print the whole week to user from Monday till Sunday.
To find the days since Monday, subtract 1, but use modulo math and avoid negative numbers. %
matches the classic functionality of modulo with positive arguments, but differs with negative ones.
#define DaysPerWeek 7
int days_since_Monday = (days_since_Sunday + DaysPerWeek - 1) % DaysPerWeek;
To print the week, start with the given date and subtract the offset:
// Move date back to Monday
time.tm_mday -= days_since_Monday;
for (int d=0; d<DaysPerWeek; d++) {
mktime(&time); // adjust for end of month, year issues.
strftime(buffer, sizeof buffer, "%A %d. %B %Y\n", &time);
printf("%s", buffer);
time.tm_mday++; // advance to tomorrow
}
Note: using time
as in struct tm time
is OK, but is a bit confusing given the standard function time()
. Consider using a different name. Perhaps struct tm timestamp_ymd
.
Robust code would add error checking:
if (mktime(&time) == (time_t)-1) Handle_Error();
Upvotes: 5