如何从给定的参数获得一周的第一天并打印整周从星期一到星期日?

时间:2017-05-01 12:56:19

标签: c date datetime time

我正在处理一个函数,我从用户那里获取参数,找出该周的第一天是什么,然后将整个星期打印给用户。

这是我到目前为止所做的:

#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;
}    

}

然后我开始尝试使用代码来获取一周的第一天。我试图通过确定它是哪个工作日然后减去​​日期为星期一之前的所有日期来获得一周的第一天。然后我可以从周一到周日开始打印整周。 例如,如果wday是星期六(6):

if(rightTime == 6)
{
    time.tm_mday = time.tm_mday - 6;
}
time.tm_wday = mktime(&time);

它仍然没有感觉到正确的方法,但我无法弄清楚如何找出该周的第一天,刷新所有信息,然后将其打印出来供用户使用。

如果日,月和年的参数将是例如2017年4月20日的正确输出:

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

感谢所有帮助!

1 个答案:

答案 0 :(得分:4)

mktime()使用struct tm中的许多成员,因此在未设置这些成员的情况下调用mktime()会导致未定义的行为(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);

mktime()之后,设置了星期几的成员。

int days_since_Sunday = time.tm_wday; // 0 - 6
  

...如何查找给定周的第一天,刷新所有信息,然后将其打印出来供用户使用。 ...从周一到周日将整周打印给用户。

要查找自星期一以来的天数,减去1,但使用模数学并避免使用负数。 % modulo 的经典功能与正参数匹配,但differs与负参数匹配。

#define DaysPerWeek 7
int days_since_Monday = (days_since_Sunday + DaysPerWeek - 1) % DaysPerWeek;

要打印周,请从给定日期开始并减去偏移量:

// 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
}

注意:在time中使用struct tm time是可以的,但鉴于标准函数time(),有点令人困惑。考虑使用其他名称。也许是struct tm timestamp_ymd

强大的代码会添加错误检查:

if (mktime(&time) == (time_t)-1) Handle_Error();