- commit
- 230e49bd4ff02c5f7436b9dc101256db351e552c
- parent
- cee0783c737a66ac477878ba3f99c81135de4e2a
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2023-06-04 12:27
feature: ranges
Diffstat
| M | calendar.c | 55 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
| M | test.c | 33 | +++++++++++++++++++++++++++++++++ |
2 files changed, 85 insertions, 3 deletions
diff --git a/calendar.c b/calendar.c
@@ -25,6 +25,7 @@ 25 25 * 1999/06/15* June 15 (usefull for birthdays) 26 26 * 1999/05/Sun+2 second Sunday in May 1999 27 27 * 1999/06/15+2 June 15 1999 and every second week since then -1 28 * 1999/06/15:1999/06/20 From June 15 1999 to June 20 1999 28 29 * 29 30 * # removed formats (mostly alternative formats) 30 31 * Jun. 15 06/15 @@ -51,6 +52,9 @@ struct tpl { 51 52 int year; 52 53 int month; 53 54 int day; -1 55 int end_year; -1 56 int end_month; -1 57 int end_day; 54 58 int repeat; 55 59 int weekday; /* starting with sunday */ 56 60 int nth_of_month; @@ -81,6 +85,9 @@ struct tpl mktpl(void) { 81 85 .year=0, 82 86 .month=0, 83 87 .day=0, -1 88 .end_year=0, -1 89 .end_month=0, -1 90 .end_day=0, 84 91 .repeat=0, 85 92 .weekday=0, 86 93 .nth_of_month=0, @@ -141,11 +148,38 @@ bool date_comp(struct tm a, struct tm b) { 141 148 } 142 149 143 150 bool is_match(struct tpl tpl, struct tm date) { -1 151 struct tm reference; -1 152 time_t delta; -1 153 int delta_days; -1 154 -1 155 if (tpl.end_day) { -1 156 if (tpl.day && tpl.month && tpl.year && tpl.end_month && tpl.end_year) { -1 157 reference = mkdate(tpl.year, tpl.month, tpl.day); -1 158 delta = difftime(mktime(&reference), mktime(&date)); -1 159 delta_days = delta / 60 / 60 / 24; -1 160 if (delta_days > 0) { -1 161 return false; -1 162 } -1 163 -1 164 reference = mkdate(tpl.end_year, tpl.end_month, tpl.end_day); -1 165 delta = difftime(mktime(&reference), mktime(&date)); -1 166 delta_days = delta / 60 / 60 / 24; -1 167 if (delta_days < 0) { -1 168 return false; -1 169 } -1 170 -1 171 return true; -1 172 } else { -1 173 fprintf(stderr, "Error: incomplete range\n"); -1 174 exit(1); -1 175 } -1 176 } -1 177 144 178 if (tpl.repeat) { 145 179 if (tpl.day && tpl.month && tpl.year) {146 -1 struct tm reference = mkdate(tpl.year, tpl.month, tpl.day);147 -1 time_t delta = difftime(mktime(&reference), mktime(&date));148 -1 int delta_days = delta / 60 / 60 / 24;-1 180 reference = mkdate(tpl.year, tpl.month, tpl.day); -1 181 delta = difftime(mktime(&reference), mktime(&date)); -1 182 delta_days = delta / 60 / 60 / 24; 149 183 if (delta_days % (7 * tpl.repeat) != 0) { 150 184 return false; 151 185 } @@ -268,6 +302,21 @@ struct tpl parse_date(char *s) { 268 302 if (!star) { 269 303 tpl.year = match.tm_year + 1900; 270 304 } -1 305 if (strchr(s, ':')) { -1 306 strtok(s, ":"); -1 307 char *s_n = strtok(NULL, ""); -1 308 if (s_n == NULL) { -1 309 invalid_date(s); -1 310 exit(1); -1 311 } else if (strptime(s_n, "%Y/%m/%d", &match)) { -1 312 tpl.end_month = match.tm_mon + 1; -1 313 tpl.end_day = match.tm_mday; -1 314 tpl.end_year = match.tm_year + 1900; -1 315 } else { -1 316 invalid_date(s); -1 317 exit(1); -1 318 } -1 319 } 271 320 tpl.repeat = n; 272 321 return tpl; 273 322 } else if (strptime(s, "%m/%d", &match)) {
diff --git a/test.c b/test.c
@@ -171,6 +171,20 @@ char *test_parse_date_yyyymmdd_repeat(void) {
171 171 return 0;
172 172 }
173 173
-1 174 char *test_parse_date_range(void) {
-1 175 struct tpl actual = parse_date_mut("1999/03/01:2000/05/02");
-1 176 struct tpl expected = mktpl();
-1 177 expected.year = 1999;
-1 178 expected.month = 3;
-1 179 expected.day = 1;
-1 180 expected.end_year = 2000;
-1 181 expected.end_month = 5;
-1 182 expected.end_day = 2;
-1 183
-1 184 mu_assert("1999/03/01:2000/05/02", tpl_comp(actual, expected));
-1 185 return 0;
-1 186 }
-1 187
174 188 char *test_parse_date_weekday(void) {
175 189 struct tpl actual = parse_date_mut("Sat");
176 190 struct tpl expected = mktpl();
@@ -288,6 +302,23 @@ char *test_is_match_yyyymmdd_repeat(void) {
288 302 return 0;
289 303 }
290 304
-1 305 char *test_is_match_range(void) {
-1 306 struct tpl tpl = mktpl();
-1 307 tpl.year = 1999;
-1 308 tpl.month = 2;
-1 309 tpl.day = 13;
-1 310 tpl.end_year = 2000;
-1 311 tpl.end_month = 3;
-1 312 tpl.end_day = 15;
-1 313
-1 314 mu_assert("start does match", is_match(tpl, mkdate(1999, 2, 13)));
-1 315 mu_assert("end does match", is_match(tpl, mkdate(2000, 3, 15)));
-1 316 mu_assert("between does match", is_match(tpl, mkdate(1999, 8, 2)));
-1 317 mu_assert("before start does not match", !is_match(tpl, mkdate(1999, 2, 12)));
-1 318 mu_assert("after end does not match", !is_match(tpl, mkdate(2000, 3, 16)));
-1 319 return 0;
-1 320 }
-1 321
291 322 char *test_is_match_weekday(void) {
292 323 struct tpl tpl = mktpl();
293 324 tpl.weekday = 7;
@@ -400,6 +431,7 @@ int main(int argc, char **argv) {
400 431 mu_test("parses yyyy/mm/dd", test_parse_date_yyyymmdd);
401 432 mu_test("parses yyyy/mm/dd*", test_parse_date_yyyymmdd_star);
402 433 mu_test("parses yyyy/mm/dd+n", test_parse_date_yyyymmdd_repeat);
-1 434 mu_test("parses yyyy/mm/dd:yyyy/mm/dd", test_parse_date_range);
403 435 mu_test("parses weekday", test_parse_date_weekday);
404 436 mu_test("parses weekday+n", test_parse_date_weekday_with_nth_of_month);
405 437 mu_test("parses weekday-n", test_parse_date_weekday_with_nth_last_of_month);
@@ -413,6 +445,7 @@ int main(int argc, char **argv) {
413 445 mu_test("matches mm/dd", test_is_match_mmdd);
414 446 mu_test("matches yyyy/mm/dd", test_is_match_yyyymmdd);
415 447 mu_test("matches yyyy/mm/dd+n", test_is_match_yyyymmdd_repeat);
-1 448 mu_test("matches yyyy/mm/dd:yyyy/mm/dd", test_is_match_range);
416 449 mu_test("matches weekday", test_is_match_weekday);
417 450 mu_test("matches weekday+n", test_is_match_weekday_with_nth_of_month);
418 451 mu_test("matches weekday-n", test_is_match_weekday_with_nth_last_of_month);