/* acq_bizday.c - business-day arithmetic (leaf util). */
#include <stdio.h>
#include "acq_common.h"

static int is_leap(int y) { return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0); }

static int mdays(int y, int m)
{
    static const int d[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    if (m == 2 && is_leap(y)) return 29;
    return d[m - 1];
}

/* Sakamoto's algorithm: day of week 0=Sun..6=Sat. */
static int dow(int y, int m, int d)
{
    static int t[] = {0,3,2,5,0,3,5,1,4,6,2,4};
    if (m < 3) y -= 1;
    return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

int acq_next_bizday(const char *in, char *out)
{
    int y, m, d;
    if (in == 0 || out == 0) return -1;
    if (sscanf(in, "%d-%d-%d", &y, &m, &d) != 3) return -1;
    if (m < 1 || m > 12 || d < 1 || d > 31) return -1;

    do {
        d++;
        if (d > mdays(y, m)) { d = 1; m++; if (m > 12) { m = 1; y++; } }
    } while (dow(y, m, d) == 0 || dow(y, m, d) == 6);   /* skip Sun/Sat */

    sprintf(out, "%04d-%02d-%02d", y, m, d);
    return 0;
}
