date.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       date.c (1858B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <ctype.h>
            3 #include <stdio.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 #include <time.h>
            7 
            8 #include "util.h"
            9 
           10 static void
           11 usage(void)
           12 {
           13         eprintf("usage: %s [-u] [-d time] [+format | mmddHHMM[[CC]yy]]\n", argv0);
           14 }
           15 
           16 static int
           17 datefield(const char *s, size_t i)
           18 {
           19         if (!isdigit(s[i]) || !isdigit(s[i+1]))
           20                 eprintf("invalid date format: %s\n", s);
           21 
           22         return (s[i] - '0') * 10 + (s[i+1] - '0');
           23 }
           24 
           25 static void
           26 setdate(const char *s, struct tm *now)
           27 {
           28         struct tm date;
           29         struct timespec ts;
           30 
           31         switch (strlen(s)) {
           32         case 8:
           33                 date.tm_year = now->tm_year;
           34                 break;
           35         case 10:
           36                 date.tm_year = datefield(s, 8);
           37                 if (date.tm_year < 69)
           38                         date.tm_year += 100;
           39                 break;
           40         case 12:
           41                 date.tm_year = ((datefield(s, 8) - 19) * 100) + datefield(s, 10);
           42                 break;
           43         default:
           44                 eprintf("invalid date format: %s\n", s);
           45                 break;
           46         }
           47 
           48         date.tm_mon = datefield(s, 0) - 1;
           49         date.tm_mday = datefield(s, 2);
           50         date.tm_hour = datefield(s, 4);
           51         date.tm_min = datefield(s, 6);
           52         date.tm_sec = 0;
           53         date.tm_isdst = -1;
           54 
           55         ts.tv_sec = mktime(&date);
           56         if (ts.tv_sec == -1)
           57                 eprintf("mktime:");
           58         ts.tv_nsec = 0;
           59 
           60         if (clock_settime(CLOCK_REALTIME, &ts) == -1)
           61                 eprintf("clock_settime:");
           62 }
           63 
           64 int
           65 main(int argc, char *argv[])
           66 {
           67         struct tm *now;
           68         time_t t;
           69         char buf[BUFSIZ], *fmt = "%a %b %e %H:%M:%S %Z %Y";
           70 
           71         t = time(NULL);
           72         if (t == -1)
           73                 eprintf("time:");
           74 
           75         ARGBEGIN {
           76         case 'd':
           77                 t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
           78                 break;
           79         case 'u':
           80                 if (setenv("TZ", "UTC0", 1) < 0)
           81                         eprintf("setenv:");
           82                 break;
           83         default:
           84                 usage();
           85         } ARGEND
           86 
           87         if (!(now = localtime(&t)))
           88                 eprintf("localtime:");
           89         if (argc) {
           90                 if (argc != 1)
           91                         usage();
           92                 if (argv[0][0] != '+') {
           93                         setdate(argv[0], now);
           94                         return 0;
           95                 }
           96                 fmt = &argv[0][1];
           97         }
           98 
           99         strftime(buf, sizeof(buf), fmt, now);
          100         puts(buf);
          101 
          102         return fshut(stdout, "<stdout>");
          103 }