sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | 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 }