Host C Specs


Directory: src/c/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 33 / 0 / 33
Functions: 100.0% 10 / 0 / 10
Branches: 86.7% 26 / 0 / 30

core/clock/date.c
Line Branch Exec Source
1 /**
2 * @file date.c
3 * @brief Pure calendar math, host-testable off-device.
4 *
5 * @ingroup lib_core
6 */
7 #include "clock/date.h"
8
9 /**
10 * @brief Whether a year is a leap year, by the usual rule.
11 *
12 * Every fourth year is one, except a century year, unless it also divides evenly by 400.
13 *
14 * @param year The full year (2026, not 126).
15 * @return True when the year has a leap day, false when it does not.
16 */
17 6 static int is_leap(int year)
18 {
19
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 3 times.
6 return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
20 }
21
22 /**
23 * @brief The weekday December 31st lands on for a year.
24 *
25 * @param year The full year (2026, not 126).
26 * @return The weekday, 0 Sunday to 6 Saturday.
27 */
28 15 static int dec31_wday(int year)
29 {
30 15 return (year + year / 4 - year / 100 + year / 400) % 7;
31 }
32
33 12 int date_iso_weeks_in_year(int year)
34 {
35 // 53 when the year ends on a Thursday or the year before it ended on a Wednesday
36
3/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
12 return 52 + (dec31_wday(year) == 4 || dec31_wday(year - 1) == 3 ? 1 : 0);
37 }
38
39 /**
40 * @brief The week number worked out from the date alone, before the year boundary is taken
41 * into account.
42 *
43 * A number below 1 means the day belongs to last year's final week. A number above the year's
44 * own total means it already belongs to next year's week 1. The ISO weekday used here runs
45 * Monday as 1 through Sunday as 7.
46 *
47 * @param yday The day of the year counting January 1st as 0 (like tm_yday).
48 * @param wday The weekday, 0 Sunday to 6 Saturday.
49 * @return The raw week number, which may fall outside 1 to the year's own week count.
50 */
51 11 static int raw_week(int yday, int wday)
52 {
53
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 int iso_wday = wday == 0 ? 7 : wday;
54 11 return (yday + 1 - iso_wday + 10) / 7;
55 }
56
57 7 int date_iso_week(int year, int yday, int wday)
58 {
59 7 int week = raw_week(yday, wday);
60
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (week < 1)
61 {
62 // the first days of January can still belong to last year's final week
63 3 return date_iso_weeks_in_year(year - 1);
64 }
65
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3 times.
4 if (week > date_iso_weeks_in_year(year))
66 {
67 // the last days of December can already belong to next year's week 1
68 1 return 1;
69 }
70
71 3 return week;
72 }
73
74 4 int date_iso_week_year(int year, int yday, int wday)
75 {
76 4 int week = raw_week(yday, wday);
77
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (week < 1)
78 {
79 2 return year - 1;
80 }
81
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 if (week > date_iso_weeks_in_year(year))
82 {
83 1 return year + 1;
84 }
85
86 1 return year;
87 }
88
89 3 int date_day_of_year(int yday)
90 {
91 3 return yday + 1;
92 }
93
94 2 int date_days_left_in_year(int year, int yday)
95 {
96
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 return (is_leap(year) ? 366 : 365) - date_day_of_year(yday);
97 }
98
99 5 int date_days_in_month(int year, int mon0)
100 {
101 static const unsigned char days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
102
3/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 4 times.
5 if (mon0 < 0 || mon0 > 11)
103 {
104 1 return 0;
105 }
106
107
3/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
4 return days[mon0] + (mon0 == 1 && is_leap(year) ? 1 : 0);
108 }
109
110 2 int date_first_wday(int wday, int mday)
111 {
112 // walk today's weekday back to the 1st of the month
113 2 return (wday - (mday - 1) % 7 + 7) % 7;
114 }
115