Command line utility to display timestamps

A timestamps, also known as Unix epoch, is the number of seconds since 1-1-1970. The C language provides for translating timestamps to and from human readable formats. I had found no utility for doing the same from the command line, when I coded the short program below.

The compile command at the top comment assumes you save it as time_t.c and put the executable in your bin directory.

update: Found out:

~$ date +%s
1539708369
~$ date --date=@1539708369
Tue Oct 16 18:46:09 CEST 2018
001: /*
002: command line to compile:
003: 
004:    gcc -std=gnu99 -o ~/bin/time_t time_t.c
005: */
006: #undef _NO_OLDNAMES
007: #undef RC_INVOKED
008: #include <time.h>
009: //extern void tzset(void);
010: #include <stdio.h>
011: #include <stdlib.h>
012: #include <string.h>
013: #include <ctype.h>
014: 
015: int main(int argc, char *argv[])
016: {
017:    int i, rc = 0, tz_expected = 0;
018:    long my_tz;
019: 
020:    tzset();
021:    my_tz = -timezone; // daylight is not meaningful
022: 
023:    if (argc <= 1 || strcmp(argv[1], "-h") == 0)
024:    {
025:       printf(
026:          "Arguments passed as dates, yyyy-mm-dd[Thh:mm:ss], yy.mm.dd [hh:mm:ss],\n"
027:          "dd/mm/yyyy [hh:mm:ss], \"now\", or number, are echoed in three formats.\n"
028:          "Numbers with leading 0 or 0x are octal or hex, except after punctuation\n"
029:          "-z 3600 sets timezone 1 hour West of UTC, default is -(%ld - %d hour DST).\n"
030:          "-Z 1 is the same as -z 3600.\n",
031:             timezone, daylight);
032:       return 0;
033:    }
034: 
035:    for (i = 1; i < argc; ++i)
036:    {
037:       char *t = NULL;
038:       unsigned long ul;
039:       if (tz_expected == 0 && strcasecmp(argv[i], "now") == 0)
040:          ul = time(0);
041:       else
042:          ul = strtoul(argv[i], &t, 0);
043:       int rtc = 1;
044: 
045:       if (tz_expected)
046:       {
047:          my_tz = ul * (long)tz_expected;
048:          tz_expected = 0;
049:          continue;
050:       }
051:       else if (strcmp(argv[i], "-z") == 0)
052:       {
053:          tz_expected = 1;
054:          continue;
055:       }
056:       else if (strcmp(argv[i], "-Z") == 0)
057:       {
058:          tz_expected = 3600;
059:          continue;
060:       }
061: 
062:       if (ul > 0 && t && ispunct(*t)) // convert from yyyy-mm-ddThh:mm:ss
063:       {
064:          struct tm tm;
065:          char *p = t + 1;
066:          unsigned long first = ul, last = 0;
067:          memset(&tm, 0, sizeof tm);
068: 
069:          ul = strtoul(p, &t, 10);
070:          if (ul > 0 && ispunct(*t))
071:          {
072:             tm.tm_mon = ul - 1;
073:             p = t + 1;
074:             ul = strtoul(p, &t, 10);
075:             if (ul > 0)
076:             {
077:                last = ul;
078:                if (*t) // can be 'T', space, or whatever
079:                {
080:                   p = t + 1;
081:                   ul = strtoul(p, &t, 10);
082:                   if (*t == ':')
083:                   {
084:                      tm.tm_hour = (int)ul;
085:                      p = t + 1;
086:                      ul = strtoul(p, &t, 10);
087:                      if (*t == ':')
088:                      {
089:                         tm.tm_min = (int)ul;
090:                         p = t + 1;
091:                         ul = strtoul(p, &t, 10);
092:                         if (*t == 0)
093:                            tm.tm_sec = (int)ul;
094:                      }
095:                   }
096:                }
097:             }
098:          }
099:          if (last < 1900)
100:          {
101:             tm.tm_mday = (int)last;
102:             if (first > 1900)
103:                first -= 1900;
104:             else
105:                first += 100;
106:             tm.tm_year = (int)first;
107:          }
108:          else
109:          {
110:             tm.tm_mday = (int)first;
111:             tm.tm_year = (int)last - 1900;
112:          }
113:          ul = mktime(&tm);    // convert to localtime w/o DST
114:          if ((long)ul != -1L) // then adjust timezone
115:             ul -= timezone;
116:       }
117: 
118:       if ((long)ul < 0 || t && *t != 0)
119:       {
120:          fprintf(stderr, "invalid argument %s\n", argv[i]);
121:       }
122:       else
123:       {
124:          time_t tt = (time_t)(ul + my_tz);
125:          struct tm *t = gmtime(&tt);
126:          if (t)
127:          {
128:             char stz[80];
129:             struct tm tm = *t;
130: 
131:             if (my_tz)
132:                sprintf(stz, "%+02ld:%02ld", my_tz /3600L, my_tz%3600L);
133:             else
134:                strcpy(stz, "Z");
135: 
136:             fprintf(stdout, // RFC 3339
137:                "%#lx = %lu = %04d-%02d-%02dT%02d:%02d:%02d%s (%s)\n",
138:                ul, ul,
139:                tm.tm_year + 1900,
140:                tm.tm_mon+1,
141:                tm.tm_mday,
142:                tm.tm_hour,
143:                tm.tm_min,
144:                tm.tm_sec,
145:                stz,
146:                argv[i]);
147:             rtc = 0;
148:          }
149:       }
150:       rc += rtc;
151:    }
152:    if (rc)
153:       fprintf(stderr, "exiting with rtc=%d\n", rc);
154:    return rc;
155: }
156: 
zero rights

Copy and paste the script to your editor of choice. There is a Javascript for that. Otherwise, you may just download it.