Operating System - HP-UX
1745817 Members
3860 Online
108722 Solutions
New Discussion юеВ

convert human readable to epoch secs

 
SOLVED
Go to solution
Shabu Khan-2
Frequent Advisor

convert human readable to epoch secs

Hello Folks,
There are numerous postings on converting human date to epoch, but I am looking for a perl or shell one-liner.
I am doing some automation and bumped into a date validation and time elapsed since a particular date, the output that I get from a query for particular timestamp column is in this format:
14-JAN-2010 17:21:38

I need to pass this value and use the built-in perl localtime/date functions to output this format to epoch secs.

From going through these forums, I can convert current date to epoch and the output of that to the format that I want, but how do I convert the same format back to epoch?

##Convert current time to epoch secs
# perl -e "print time"

## Convert epoch to a timestamp format that I want
# perl -MPOSIX -e 'print strftime "%Y-%m-%d %H:%M:%S\n",localtime(1263520672)'

## Convert the same timestamp (%Y-%m-%d %H:%M:%S) format to epoch?
???

Thanks,
12 REPLIES 12
Michal Kapalka (mikap)
Honored Contributor

Re: convert human readable to epoch secs

Shabu Khan-2
Frequent Advisor

Re: convert human readable to epoch secs

Thanks.
That helps a little bit, but I am still playing around with it, doesn't give me the correct info yet ..

Timestamp is 14-JAN-2010 20:33:38
#perl -MTime::Local -le '$epoch_secs = timegm(38,33,20,14,01,110); print "$epoch_secs";'
1266179618

#perl -e "print scalar(localtime(1266179618))"
Sun Feb 14 12:33:38 2010

Returns incorrect info?
Shabu Khan-2
Frequent Advisor

Re: convert human readable to epoch secs

hmm... interesting, further reading on the web says timelocal month param starts from 00 thru 11 (Jan thru Dec) ... that answers why it was returning Feb ...

Other solutions are welcome too ...

I'll leave this thread Open ...

Thanks,
James R. Ferguson
Acclaimed Contributor

Re: convert human readable to epoch secs

Hi:

Here's a small script that lets you pass a date and time argument. It converts this to epoch seconds for output. Leading zeros in the input fields are unnecessary, and the month name can be either lower or uppercase letters or mixed.

# cat ./mytime
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
my %months =
( 'JAN'=>1, 'FEB'=>2, 'MAR'=>3, 'APR'=>4, 'MAY'=>5, 'JUN'=>6,
'JUL'=>7, 'AUG'=>8, 'SEP'=>9, 'OCT'=>10, 'NOV'=>11, 'DEC'=>12
);
my $date = shift or die "DD-MMM-YYYY expected\n";
my $time = shift or die "HH:MM:SS expected\n";
my ( $mday, $mon, $year ) = split /-/, $date;
my ( $hours, $min, $sec ) = split /:/, $time;
print timelocal($sec,$min,$hours,$mday,$months{uc($mon)}-1,$year-1900),"\n";
1;

...run as:

# ./mytime 14-JAN-2010 17:21:38
1263507698
# perl -le 'print scalar localtime(1263507698)'
Thu Jan 14 17:21:38 2010

# ./mytime 8-Apr-2010 8:17:23
1270729043
# perl -wle 'print scalar localtime(1270729043)'
Thu Apr 8 08:17:23 2010

Regards!

...JRF...
john korterman
Honored Contributor
Solution

Re: convert human readable to epoch secs

Hi Shabu,

I assume that your first perl statement sums a number of values and "01" in (38,33,20,14,01,110) will include the full first month - which it should not as long as we are still in January.
You need to convert JAN to 00, FEB to 01, etc., before feeding it to your first perl command,e.g.:

#!/usr/bin/sh
TIMESTAMP="14-JAN-2010 17:21:38"

export DA=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $1}')
export MO=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $2}')
export YE=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $3}')
export HO=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $4}')
export MI=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $5}')
export SE=$(echo "$TIMESTAMP"| awk -F"(-|:|\ )" '{print $6}')

case $MO in
JAN) MO=00;;
FEB) MO=01;;
MAR) MO=02;;
# fill in your month representation....
esac;

SECONDS=$(perl -MTime::Local -le '$epoch_secs = timegm($ENV{'SE'},$ENV{'MI'},$ENV{'HO'},$ENV{'DA'},$ENV{'MO'},$ENV{'YE'}); print "$epoch_secs";')

echo $SECONDS

echo "0d${SECONDS}=y"| adb
# end of example

regards,
John K.

it would be nice if you always got a second chance
mvpel
Trusted Contributor

Re: convert human readable to epoch secs

In your example in the second response, you're also going to get incorrect results by using timegm() to go to epoch, and then localtime() to convert back for your test.

You need to use timegm() and gmtime() together, or timelocal() and localtime() together, in order to get the same thing out as what you put in.

The timelocal() and timegm() functions use the same array format as localtime() and gmtime(), as you discovered, with month = 0..11
Shabu Khan-2
Frequent Advisor

Re: convert human readable to epoch secs

Thanks for responding folks. I got this done last night after the pointer from mikap.

Here is how I got this done ... part of the script ...

......
JOB_ID="$(echo ${LINE} | cut -d '|' -f1)"
START_TIME="$(echo ${LINE} | cut -d '|' -f2)"
STATUS="$(echo ${LINE} | awk '{print $NF}')"

export SS="$(echo ${START_TIME} | cut -d_ -f1)"
export MM="$(echo ${START_TIME} | cut -d_ -f2)"
export HH="$(echo ${START_TIME} | cut -d_ -f3)"
export DD="$(echo ${START_TIME} | cut -d_ -f4)"
export MM="$(echo ${START_TIME} | cut -d_ -f5)"
export YY="$(echo ${START_TIME} | cut -d_ -f6)"

START_TIME_IN_EPOCH_SECS="$(perl -MTime::Local -le '$epoch_secs = timelocal('$SS','$MM','$HH','$DD','$MM','$YY'); print "$epoch_secs";')"
CURR_TIME_IN_EPOCH_SECS="$(perl -le "print time")"
ELAPSED_TIME_IN_EPOCH_SECS="$(expr ${CURR_TIME_IN_EPOCH_SECS} - ${START_TIME_IN_EPOCH_SECS})"
ELPASED_TIME_IN_MINS="$(echo ${ELAPSED_TIME_IN_EPOCH_SECS}/60 | bc)"

......

Kind of the same way that John suggested.

Thanks,
Shabu Khan-2
Frequent Advisor

Re: convert human readable to epoch secs

Not sure where my new 'reopen' thread went ...

This is what I was asking...

Reopening ...

I am running to a weird condition ...
the Output that I am parsing is this:
16295|38_08_12_19_JAN_2010|||STARTED


# perl -MTime::Local -le '$epoch_secs = timelocal('${SS}','${MM}','${HH}','${DD}','${MON}','${YY}'); print "$epoch_secs";'
Illegal octal digit '8' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

12:08 pm is the time that this job started.
Anyone know why its complaining about '08' Minutes - ${MM} variable?
James R. Ferguson
Acclaimed Contributor

Re: convert human readable to epoch secs

Hi (again):

> Anyone know why its complaining about '08' Minutes - ${MM} variable?

Yes, this is your *shell* interpreting the leading zero as signifying an *octal* value. If would need to drop the leading zero.

Of course if you use my slightly larger script, you can pass leading zeros or not :-)

Regards!

...JRF...