问题
I have a string in format 20141225093000
which represents Dec 25, 2014 09:30:00
and I want to convert the original format to a unix timestamp format so i can do time operations on it.How would I do this in bash?
I can easily parse out the values with expr
but I was hoping to be able to identify a format like YYYYmmddHHMMSS and then convert it based on that.
回答1:
With GNU date, you can convert YYYY-MM-DDTHH:MM:SS
to epoch time (seconds since 1-1-1970) easily, like so:
date -d '2014-12-25T09:30:00' +%s
To do this starting without any delimiters:
in=20141225093000
rfc_form="${in:0:4}-${in:4:2}-${in:6:2}T${in:8:2}:${in:10:2}:${in:12:2}"
epoch_time=$(date -d "$rfc_form" +%s)
回答2:
You need to transform the string before calling date
:
#!/bin/bash
s="20141225093000"
s=$(perl -pe 's/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/$1-$2-$3 $4:$5:$6/g' <<< "$s")
date -d "$s" +%s
Yet another way:
perl -MDate::Parse -MPOSIX -le '$s="20141225093000"; $s =~ s/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/$1-$2-$3 $4:$5:$6/g ; print str2time($s);'
1419499800
回答3:
This Bash function does the conversion with builtins:
# Convert UTC datetime string (YYYY-MM-DD hh:mm:ss) to Unix epoch seconds
function ymdhms_to_epoch
{
local -r ymdhms=${1//[!0-9]} # Remove non-digits
if (( ${#ymdhms} != 14 )) ; then
echo "error - '$ymdhms' is not a valid datetime" >&2
return 1
fi
# Extract datetime components, possibly with leading zeros
local -r year=${ymdhms:0:4}
local -r month_z=${ymdhms:4:2}
local -r day_z=${ymdhms:6:2}
local -r hour_z=${ymdhms:8:2}
local -r minute_z=${ymdhms:10:2}
local -r second_z=${ymdhms:12:2}
# Remove leading zeros from datetime components to prevent them
# being treated as octal values
local -r month=${month_z#0}
local -r day=${day_z#0}
local -r hour=${hour_z#0}
local -r minute=${minute_z#0}
local -r second=${second_z#0}
# Calculate Julian Day Number (jdn)
# (See <http://en.wikipedia.org/wiki/Julian_day>, Calculation)
local -r -i a='(14-month)/12'
local -r -i y=year+4800-a
local -r -i m=month+12*a-3
local -r -i jdn='day+(153*m+2)/5+365*y+(y/4)-(y/100)+(y/400)-32045'
# Calculate days since the Unix epoch (1 Jan. 1970)
local -r -i epoch_days=jdn-2440588
local -r -i epoch_seconds='((epoch_days*24+hour)*60+minute)*60+second'
echo $epoch_seconds
return 0
}
Example usage:
$ ymdhms_to_epoch '1970-01-01 00:00:00'
0
$ ymdhms_to_epoch '2014-10-18 00:10:06'
1413591006
$ ymdhms_to_epoch '2014-12-25 09:30:00'
1419499800
回答4:
GNU awk:
gawk -v t=20141225093000 'BEGIN {gsub(/../, "& ", t); sub(/ /,"",t); print mktime(t)}'
If GNU date is not available, then it's likely GNU awk may not be. Perl probably has the highest chance of being available. This snippet uses strptime
so you don't have to parse the time string at all:
perl -MTime::Piece -E 'say Time::Piece->strptime(shift, "%Y%m%d%H%M%S")->epoch' 20141225093000
来源:https://stackoverflow.com/questions/26432050/bash-convert-string-to-timestamp