/* * util_date.c - 일자/영업일 유틸리티 (plain C, 공유) */ #include "acq_util.h" #include #include #include #include static int is_all_digit(const char *s, int len) { int i; for (i = 0; i < len; i++) if (!isdigit((unsigned char)s[i])) return 0; return 1; } static int to_int(const char *s, int len) { int i, v = 0; for (i = 0; i < len; i++) v = v * 10 + (s[i] - '0'); return v; } static int days_in_month(int y, int m) { static const int d[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (m < 1 || m > 12) return 0; if (m == 2) { int leap = (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0); return leap ? 29 : 28; } return d[m - 1]; } int date_is_valid(const char *yyyymmdd) { int y, m, d; if (!yyyymmdd || strlen(yyyymmdd) < 8) return 0; if (!is_all_digit(yyyymmdd, 8)) return 0; y = to_int(yyyymmdd, 4); m = to_int(yyyymmdd + 4, 2); d = to_int(yyyymmdd + 6, 2); if (y < 1900 || y > 2999) return 0; if (m < 1 || m > 12) return 0; if (d < 1 || d > days_in_month(y, m)) return 0; return 1; } int date_weekday(const char *yyyymmdd) { static const int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; int y, m, d; if (!date_is_valid(yyyymmdd)) return -1; y = to_int(yyyymmdd, 4); m = to_int(yyyymmdd + 4, 2); d = to_int(yyyymmdd + 6, 2); if (m < 3) y -= 1; return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7; } int date_is_weekend(const char *yyyymmdd) { int w = date_weekday(yyyymmdd); return (w == 0 || w == 6) ? 1 : 0; } static void add_one_day(const char *in, char *out) { int y = to_int(in, 4); int m = to_int(in + 4, 2); int d = to_int(in + 6, 2); d++; if (d > days_in_month(y, m)) { d = 1; m++; if (m > 12) { m = 1; y++; } } snprintf(out, 9, "%04d%02d%02d", y, m, d); } int date_next_business(const char *yyyymmdd, char *out) { char cur[9]; int guard = 0; if (!date_is_valid(yyyymmdd) || !out) return -1; memcpy(cur, yyyymmdd, 8); cur[8] = '\0'; do { add_one_day(cur, cur); if (++guard > 14) return -1; } while (date_is_weekend(cur)); memcpy(out, cur, 8); out[8] = '\0'; return 0; } void date_today(char *out) { time_t now = time(NULL); struct tm tmv; localtime_r(&now, &tmv); strftime(out, 9, "%Y%m%d", &tmv); }