git/aika/main
c/arvelie.c
99 lines3 KB last change raw · history
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <sysexits.h>

// Prints help/usage
void printHelp(const char *progName) {
    printf("Arvelie %s\n", VERSION);
    printf("Usage: %s [OPTION]... [DATE]\n", progName);
    printf("Convert the current date, or a specified date, to Arvelie format.\n\n");
    printf("Options:\n");
    printf("  -h, --help     display this help and exit\n");
    printf("  -v, --version  display version information and exit\n\n");
    printf("Arguments:\n");
    printf("  DATE           convert a specific date (formats: YYYY-MM-DD, YYYYMMDD)\n");
    printf("                 If omitted, prints the current local date.\n\n");
    printf("Examples:\n");
    printf("  %s             # Print current Arvelie date\n", progName);
    printf("  %s 2021-01-08  # Convert January 8, 2021 to Arvelie\n", progName);
}

// Core conversion logic
void printArvelie(int yearFull, int doy) {
    int y = yearFull % 100;
    const char mList[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    if (doy == 365) {
        printf("%02d+00\n", y); // Year Day
    } else if (doy == 366) {
        printf("%02d+01\n", y); // Leap Day
    } else {
        int mIndex = (doy - 1) / 14;
        int dom = (doy - 1) % 14 + 1;
        printf("%02d%c%02d\n", y, mList[mIndex], dom);
    }
}

void parseAndConvert(const char *input) {
    int y = 0, m = 0, d = 0;
    if (sscanf(input, "%4d-%2d-%2d", &y, &m, &d) == 3 ||
        sscanf(input, "%4d%2d%2d", &y, &m, &d) == 3) {
        
        if (m < 1 || m > 12 || d < 1 || d > 31) {
            fprintf(stderr, "Error: Invalid date values. Expected MM 01-12, DD 01-31.\n");
            exit(EX_DATAERR);
        }

        struct tm time_in = {0};
        time_in.tm_year = y - 1900;
        time_in.tm_mon = m - 1;
        time_in.tm_mday = d;
        time_in.tm_isdst = -1;

        if (mktime(&time_in) == -1) {
            fprintf(stderr, "Error: Could not process date.\n");
            exit(EX_DATAERR);
        }

        printArvelie(y, time_in.tm_yday + 1);
    } else {
        fprintf(stderr, "Error: Invalid date format. Use YYYY-MM-DD.\n");
        exit(EX_USAGE);
    }
}

void prArvelie(void) {
    time_t t = time(NULL);
    struct tm *tm = localtime(&t);
    printArvelie(tm->tm_year + 1900, tm->tm_yday + 1);
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        for (int i = 1; i < argc; i++) {
            if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
                printHelp(argv[0]);
                return 0;
            }
            if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
                printf("Arvelie %s\n", VERSION);
                return 0;
            }
        }

        if (argv[1][0] != '-') {
            parseAndConvert(argv[1]);
            return 0;
        } else {
            fprintf(stderr, "Error: Unknown argument '%s'\n", argv[1]);
            fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
            exit(EX_USAGE);
        }
    }

    prArvelie();
    return 0;
}