как уже упоминалось, вам нужен год, чтобы выполнить этот расчет, чтобы решить, сколько дней вам нужно сосчитать за февраль.
Я попытался решить проблему, используя следующий фрагмент кода, используя Congruence Зеллера , поскольку он не зависит от функций даты и времени. Я попытался добавить некоторые комментарии, что я делаю, где и почему, я также провел некоторые тесты, и это, кажется, работает, но могут быть некоторые крайние / угловые случаи, о которых я не думал. Я уверен, что это не оптимальное решение, не стесняйтесь давать отзывы.
#include <stdio.h>
// defines the day offsets of each month in "normal" and "leap" year
static const int days_of_months[2][13] = {
{0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};
/*
Leap year is defined as:
* divisable by 4 except divisable by 100 OR
* divisable by 400
*/
int year_is_leap(int year)
{
return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
}
// https://en.wikipedia.org/wiki/Zeller%27s_congruence
int get_day_of_the_week(int year, int month, int day)
{
int h, q, m, K, J = 0;
q = day;
m = month;
if (month < 3)
{
m = month + 12;
year -= 1;
}
K = year % 100;
J = year / 100;
h = (q + (13*(m+1))/5 + K + K/4 + J/4 + 5*J) % 7;
// remap to Sunday = 1 ... Saturday = 7
return ((h+6)%7)+1;
}
int get_days_since_first_jan (int year, int month, int week, int day)
{
int days_passed = 0, i = 0;
// if date is in week 1, use given day of week to get the days of this month
if (week == 1)
{
days_passed += day - get_day_of_the_week (year, month, 1) + 1;
}
else
{
//iterate over weeks
for (i = week; i > 0; i --)
{
// in week one, get the weekday of the first of the month, to get remaining days of this week for this month
if (i == 1)
{
days_passed += 7 - (get_day_of_the_week (year, month, 1) - 1);
}
// in the given week, simply add the given days to it
else if (i == week)
{
days_passed += day;
}
// for all other weeks, add 7 days
else
{
days_passed += 7;
}
}
}
// Add the offset of the given month in days
days_passed += days_of_months[year_is_leap (year)][month];
return days_passed;
}
int main(void)
{
// 2020/1/31 -> 31
printf("%d\n", get_days_since_first_jan(2020, 1, 5, 6));
// 2020/2/28 -> 59
printf("%d\n", get_days_since_first_jan(2020, 2, 5, 6));
// 2020/4/15 -> 106
printf("%d\n", get_days_since_first_jan(2020, 4, 3, 4));
// 2020/8/17 -> 230
printf("%d\n", get_days_since_first_jan(2020, 8, 4, 2));
// 2021/3/1 -> 60
printf("%d\n", get_days_since_first_jan(2021, 3, 1, 2));
// 2021/3/1 -> 60
printf("%d\n", get_days_since_first_jan(2021, 3, 1, 2));
// 2021/3/9 -> 68
printf("%d\n", get_days_since_first_jan(2021, 3, 2, 3));
// 2028/1/1 -> 1
printf("%d\n", get_days_since_first_jan(2028, 1, 1, 7));
// 2028/8/29 -> 242
printf("%d\n", get_days_since_first_jan(2028, 8, 5, 3));
return 0;
}