#!/usr/bin/nawk -f
# SccsId[] = "@(#)epoch_time_awk.awk 1.3 08/03/04"
BEGIN \
{
for (n=1; n<ARGC; n++)
{
if (ARGV[1] == "-z")
{
if (ARGV[2] !~ /^-?[0-9]+$/)
Usage_and_exit("Time zone must be integer (represents hours)!")
tz_adj = ARGV[2] * 3600
ARGV[2] = ""
ARGV[1] = ""
shift_ARGV()
}
else if (ARGV[1] == "-h")
Usage_and_exit()
}
if (ARGV[1] == "")
{
print secs_since_epoch()
exit 0
}
julian_table()
if (ARGV[1] ~ /[0-9][0-9][0-9][0-9][0-1][0-9][0-3][0-9][0-2][0-9][0-5][0-9][0-5][0-9]/)
{
print secs_since_epoch()
exit 0
}
epoch_sss = ARGV[1] + tz_adj
days = sprintf("%d",(epoch_sss / 86400))
sss = sprintf("%d",(epoch_sss % 86400))
sub(/^-/,"",sss)
int(sss)
ddddd = (basedate(1970,01,01) + days)
yyyymmdd = ddddd_to_yyyymmdd(ddddd)
hh = (sss / 3600.000000)
sss = (sss % 3600.000000)
mm = (sss / 60.000000)
ss = (sss % 60)
printf("%8s%02d%02d%02d\n", yyyymmdd, hh, mm, ss)
exit 0
}
function basedate(YYYY,MM,DD, yyyy,cc,ddddd,leapdays,cc_leapdays,accum_days)
{
julian_table()
yyyy = YYYY
if ((yyyy - 1) > 0)
{
yyyy--
cc = int(yyyy / 100)
ddddd = yyyy * 365
leapdays = int(yyyy / 4)
cc_leapdays = (cc > 0) ? (int(cc / 4)) : 0
ddddd = ddddd + leapdays - cc + cc_leapdays
yyyy++
}
ddddd += DD
if (leap_year(yyyy))
for (i=0; i<13; i++) accum_days[i] = julian_leap[i]
else
for (i=0; i<13; i++) accum_days[i] = julian_days[i]
ddddd += accum_days[MM += 0]
return (ddddd)
}
function ddddd_to_yyyymmdd(DDDDD, ddddd,yyyy,mmdd,i)
{
yyyy = ddddd = reduce(DDDDD)
sub(/-.*$/,"", yyyy); yyyy += 0
sub(/^.*-/,"",ddddd); ddddd += 0
if (leap_year(yyyy))
for (i in julian_leap)
julian[i] = julian_leap[i]
else
for (i in julian_days)
julian[i] = julian_days[i]
for (i=13; i>0; i--)
{
if (julian[i] < ddddd)
{
# if (leap_year(yyyy) && i > 2) ddddd++
ddddd -= julian[i]
mmdd = sprintf("%02d%02d", i, ddddd)
break
}
}
return (yyyy""mmdd)
}
function julian_table()
{
split("0 31 59 90 120 151 181 212 243 273 304 334 365", julian_days)
split("0 31 60 91 121 152 182 213 244 274 305 335 366", julian_leap)
}
function leap_year(YYYY)
{
return (((YYYY%4 == 0 && YYYY%100 != 0) || (YYYY%400 == 0)) ? 1 : 0)
}
function reduce(DDDDD, yyyy,ddddd,cc,leapdays,cc_leapdays,i)
{
for (i=1; ; i++)
{
yyyy = int(DDDDD / 365) - i
ddddd = DDDDD - yyyy * 365
cc = int(yyyy / 100)
leapdays = int(yyyy / 4)
cc_leapdays = (cc > 0) ? (int(cc / 4)) : 0
leapdays = leapdays - cc + cc_leapdays
ddddd -= leapdays
yyyy++
if (ddddd > 0) break
}
return yyyy"-"ddddd
}
function secs_since_epoch(ddddd,ddddd_yyyy,sss)
{
if (ARGV[1] == "")
"date +\%Y\%m\%d\%H\%M\%S" | getline yyyymmddhhmiss
else
yyyymmddhhmiss = sprintf("%14s",substr(ARGV[1]"00000000000000",1,14))
yyyy = substr(yyyymmddhhmiss, 1,4)
mm = substr(yyyymmddhhmiss, 5,2)
dd = substr(yyyymmddhhmiss, 7,2)
hh = substr(yyyymmddhhmiss, 9,2)
mi = substr(yyyymmddhhmiss,11,2)
ss = substr(yyyymmddhhmiss,13,2)
ddddd = basedate(yyyy,mm,dd)
ddddd_yyyy = basedate(1970,01,01)
ddddd -= ddddd_yyyy
sss = (ddddd * 86400) + (hh * 3600) + (mi * 60) + ss
sss += tz_adj
return sss
}
function shift_ARGV(i,j,k)
{
k = ARGC
for (i=1; i<=ARGC; i++)
{
if (ARGV[i] == "")
{
for (j=i+1; j<=k; j++)
{
if (ARGV[j] == "")
continue
ARGV[i] = ARGV[j]
ARGV[j] = ""
break
}
}
}
for (i=1; i<=k; i++)
if (ARGV[i] == "")
ARGC--
return ARGC
}
function Usage_and_exit(SPECIFIC_ERROR)
{
if (SPECIFIC_ERROR) print "\n"SPECIFIC_ERROR
print "\nPurpose: Return current Unix Epoch time (ssssssssss) or",
"\n convert specified Unix Epoch time to yyyymmddhhmiss",
"\n datetime, or convert yyyymmddhhmiss datetime to",
"\n Unix Epoch seconds.\n",
"\n Usage: epoch_time.awk -h -z [-]hh [yyyymmddhhmiss|ssssssssss]",
"\n e.g. epoch_time.awk [no options or arguments]",
"\n epoch_time.awk 20070121132053",
"\n epoch_time.awk 1169385653"
exit 1
}