]> Pileus Git - lackey/blob - src/util.c
Add day and week view
[lackey] / src / util.c
1 /* Time Keeping Bugs Abound! */
2
3 #include <stdio.h>
4 #include <time.h>
5
6 #include "util.h"
7
8 /* Time functions */
9 int is_leap_year(year_t year)
10 {
11         return (year % 400 == 0) ? 1 :
12                (year % 100 == 0) ? 0 :
13                (year % 4   == 0) ? 1 : 0;
14 }
15
16 int days_in_year(year_t year)
17 {
18         return 365 + is_leap_year(year);
19 }
20
21 int days_in_month(year_t year, month_t month)
22 {
23         static int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
24         int days = mdays[month];
25         if (month == FEB)
26                 days += is_leap_year(year);
27         return days;
28 }
29
30 int weeks_in_month(year_t year, month_t month)
31 {
32         int start = start_of_month(year, month);
33         int days  = days_in_month(year, month);
34         return ((start + days)-1) / 7 + 1;
35 }
36
37 wday_t day_of_week(year_t year, month_t month, day_t day)
38 {
39         static int tmp[] = {0, 3, 2, 5, 0, 3,
40                             5, 1, 4, 6, 2, 4};
41         if (month < 3)
42                 year--;
43         int start = year + year / 4
44                          - year / 100
45                          + year / 400
46                          + tmp[month];
47         return (start + day) % 7;
48 }
49
50 wday_t start_of_month(year_t year, month_t month)
51 {
52         return day_of_week(year, month, 1);
53 }
54
55 void add_days(year_t *year, month_t *month, day_t *day, int days)
56 {
57         time_t time = mktime(&(struct tm){
58                         .tm_year = *year-1900,
59                         .tm_mon  = *month,
60                         .tm_mday = *day+1,
61                         .tm_hour = 12});
62         time  += days*24*60*60;
63         struct tm *tm = localtime(&time);
64         *year  = tm->tm_year+1900;
65         *month = tm->tm_mon;
66         *day   = tm->tm_mday-1;
67 }
68
69 /* Debug functions */
70 const char *month_to_str(month_t month)
71 {
72         static const char *map[] =
73                 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
74                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", };
75         return map[month%12];
76 }
77 const char *month_to_string(month_t month)
78 {
79         static const char *map[] =
80                 { "January",   "February", "March",    "April",
81                   "May",       "June",     "July",     "August",
82                   "September", "October",  "November", "December" };
83         return map[month%12];
84 }
85
86 const char *day_to_st(wday_t day)
87 {
88         static const char *map[] =
89                 { "Su","Mo", "Tu", "We", "Th", "Fr", "Sa" };
90         return map[day%7];
91 }
92 const char *day_to_str(wday_t day)
93 {
94         static const char *map[] =
95                 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
96         return map[day%7];
97 }
98 const char *day_to_string(wday_t day)
99 {
100         static const char *map[] =
101                 { "Sunday",   "Monday", "Tuesday", "Wednesday",
102                   "Thursday", "Friday", "Saturday" };
103         return map[day%7];
104 }
105
106 /* Test functions */
107 void test_time(void)
108 {
109         printf("Year Month     Start Weeks Days\n");
110         for (int y = 2012; y <= 2012; y++)
111         for (int m = JAN;  m <= DEC;  m++) {
112                 printf("%-5d",  y);
113                 printf("%-10s", month_to_string(m));
114                 printf("%-6s",  day_to_str(start_of_month(y,m)));
115                 printf("%-6d",  weeks_in_month(y,m));
116                 printf("%-2d",  days_in_month(y,m));
117                 printf("\n");
118         }
119 }