date.c - 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… | |
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) + datefiel… | |
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 } |