#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int
main(int argc, char **argv)
{
    int option, uflg = 0, nflg = 0, iflg = 0, tflg = 0;
    time_t now;
    struct tm *tm;
    char buf[128];
    while ((option = getopt(argc, argv, "unit")) != -1) {
        if (option == 'u') uflg = 1;
        else if (option == 'n') nflg = 1;
        else if (option == 'i') iflg = 1;
        else if (option == 't') tflg = iflg = 1;
        else goto usage;
    }
    if (argc - optind > 1) goto usage;
    if (optind < argc) {
        char *end;
        intmax_t seconds;
        errno = 0;
        seconds = strtoimax(argv[optind], &end, 0);
        if (errno || !*argv[optind] || *end || (intmax_t)(time_t)seconds != seconds) goto usage;
        now = (time_t)seconds;
    } else {
        now = time(NULL);
        if (now == (time_t)-1) { perror("date: time"); return 1; }
    }
    if (nflg) printf("%jd\n", (intmax_t)now);
    else {
        tm = uflg ? gmtime(&now) : localtime(&now);
        if (tm == NULL) { perror("date: time conversion"); return 1; }
        if (!strftime(buf, sizeof(buf), iflg ?
                      (tflg ? "%Y-%m-%dT%H:%M:%S%z" : "%Y-%m-%d") :
                      "%a %b %e %H:%M:%S %Y", tm)) {
            fprintf(stderr, "date: formatting failed\n"); return 1;
        }
        if (tflg) {
            size_t n = strlen(buf);
            if (n >= 5 && strcmp(buf + n - 5, "+0000") == 0) strcpy(buf + n - 5, "Z");
        }
        puts(buf);
    }
    if (fflush(stdout) == EOF || ferror(stdout)) { perror("date: stdout"); return 1; }
    return 0;
usage:
    fprintf(stderr, "usage: %s [-unit] [seconds]\n", argv[0]);
    return 1;
}
