timedec.c (2208B)
1 /* 2 * Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <time.h> 21 22 char * 23 die(char *msg) 24 { 25 perror(msg); 26 exit(1); 27 } 28 29 char * 30 xstrptime(char *buf, char *fmt, struct tm *tm) 31 { 32 char *ep; 33 struct tm ref; 34 35 memcpy(&ref, tm, sizeof(ref)); 36 if ((ep = strptime(buf, fmt, tm))) 37 return ep; 38 memcpy(tm, &ref, sizeof(ref)); 39 return NULL; 40 } 41 42 char * 43 strptimes(char *buf, char **fmts, struct tm *tm) 44 { 45 char *ep; 46 47 for (; *fmts; ++fmts) 48 if ((ep = xstrptime(buf, *fmts, tm))) 49 return ep; 50 return NULL; 51 } 52 53 time_t 54 decodedatetime(char *s) 55 { 56 char *ep; 57 struct tm *tm; 58 time_t t; 59 60 t = time(NULL); 61 tm = localtime(&t); 62 tm->tm_hour = 0; 63 tm->tm_min = 0; 64 tm->tm_sec = 0; 65 66 ep = xstrptime(s, "%F", tm); 67 if (ep) { 68 if (ep[0] == '\0') 69 return mktime(tm); 70 else if (ep[0] != ' ') 71 return 0; 72 s = ep + 1; 73 } 74 75 ep = strptimes(s, (char *[]){ "%T", "%R", NULL }, tm); 76 if (!ep || (ep && ep[0])) 77 return 0; 78 return mktime(tm); 79 } 80 81 /* 82 * This program takes a time given in the strftime(3) format '%F' 83 * or '[%F ]%H:%M[:%S]' and outputs the time elapsed since Jan 1, 84 * 1970 00:00 in seconds. 85 * 86 * It is meant as to be a standard interface to specifying time. 87 */ 88 int 89 main(int argc, char *argv[]) 90 { 91 char *ts; 92 time_t t; 93 94 if (!argv[1]) 95 die("usage: timedec time"); 96 t = decodedatetime(argv[1]); 97 if (t == 0) 98 die("invalid time (must be of the form '%F' or '[%F ]%H:%M[:%S]')"); 99 return printf("%d\n", t) < 0; 100 }