Reputation: 1561
The date time string is in the following format: 06/12/2012 07:21:22. How can I convert it to UNIX timestamp or epoch?
Upvotes: 149
Views: 270218
Reputation: 70822
Avoiding useless repetitives forks, in order to make this translation a lot quicker...
Instead of running 1 fork for each translation, we could run date -f - +%s
as background process...
Common syntax:
epochDate=$(date -d "$InputDate" +%s)
Work fine, but become heavy if run repetetively!
In this post, you will find
bc
, rot13
, sed
...).coproc
coproc DATE { exec stdbuf -o0 /bin/date -f - +%s 2>&1 ;}
echo >&${DATE[1]} 06/12/2012 07:21:22
read -ru${DATE[0]} epochDate
printf 'EPOCH: %u Date:%(%c)T\n' $epochDate $epochDate
EPOCH: 1339478482 Date:Tue Jun 12 07:21:22 2012
About performances, you could compare:
time for i in {1..900};do echo >&${DATE[1]} "now";read -ru${DATE[0]} ans;done
real 0m0.029s
user 0m0.018s
sys 0m0.005s
and:
time for i in {1..900};do ans=$(date +%s -d "now");done
real 0m1.465s
user 0m0.962s
sys 0m0.442s
From more than 1.4 seconds to less than 30 milliseconds!!(on my host).
You could check echo $ans
, replace "now"
by "2019-25-12 20:10:00"
and so on...
myDate() {
if [[ $1 == -v ]]; then
local -n out=$2
shift 2
else
local out
fi
echo "$*" >&${DATE[1]}
read -ru ${DATE[0]} out
[[ ${out@A} == out=* ]] && echo $out
case $out in ''|*[!0-9]*) return 1;; esac
}
myDate 06/12/2012 07:21:22
1339478482
myDate -v var 06/12/2012 07:21:22
printf '%(%c)T\n' $var
Tue Jun 12 07:21:22 2012
myDate -v var wrong string
printf 'ResultCode: %d: Var: "%s"\n' "$?" "$var"
ResultCode: 1: Var: "/bin/date: invalid date 'wrong string'"
You could, once requirement of date subprocess ended:
kill ${DATE_PID}
exec {DATE[1]}>&- ; exec {DATE[0]}<&-
[1]+ Terminated coproc DATE { exec stdbuf -o0 /bin/date -f - +%s; }
Instead of running 1 fork by date to convert, run date
just 1 time and do all convertion with same process (this could become a lot quicker)!:
date -f - +%s <<eof
Apr 17 2014
May 21 2012
Mar 8 00:07
Feb 11 00:09
eof
1397685600
1337551200
1520464020
1518304140
Sample:
start1=$(LANG=C ps ho lstart 1)
start2=$(LANG=C ps ho lstart $$)
dirchg=$(LANG=C date -r .)
read -p "A date: " userdate
{ read start1 ; read start2 ; read dirchg ; read userdate ;} < <(
date -f - +%s <<<"$start1"$'\n'"$start2"$'\n'"$dirchg"$'\n'"$userdate" )
Then now have a look:
declare -p start1 start2 dirchg userdate
(may answer something like:
declare -- start1="1518549549" declare -- start2="1520183716" declare -- dirchg="1520601919" declare -- userdate="1397685600"
This was done in only one date
subprocess execution!
We just need one fifo:
mkfifo /tmp/myDateFifo
exec 7> >(exec stdbuf -o0 /bin/date -f - +%s >/tmp/myDateFifo)
exec 8</tmp/myDateFifo
rm /tmp/myDateFifo
(Note: As process is running and all descriptors are opened, we could safely remove fifo's filesystem entry.)
Then now:
LANG=C ps ho lstart 1 $$ >&7
read -u 8 start1
read -u 8 start2
LANG=C date -r . >&7
read -u 8 dirchg
read -p "Some date: " userdate
echo >&7 $userdate
read -u 8 userdate
We could buid a little function:
mydate() {
local var=$1;
shift;
echo >&7 $@
read -u 8 $var
}
mydate start1 $(LANG=C ps ho lstart 1)
echo $start1
newConnector
functionWith functions for connecting MySQL/MariaDB
, PostgreSQL
and SQLite
...
You may find them in different version on GitHub, or on my site: download or show.
wget https://raw.githubusercontent.com/F-Hauri/Connector-bash/master/shell_connector.bash
wget http://f-hauri.ch/vrac/shell_connector.sh
. shell_connector.bash
newConnector /bin/date '-f - +%s' @0 0
myDate "2018-1-1 12:00" test
echo $test
1514804400
Nota: On GitHub, functions and test are separated files. On my site test are run simply if this script is not sourced. On GitHub, there is no upgrade anymore! Last verified version is on my site!
# Exit here if script is sourced
[ "$0" = "$BASH_SOURCE" ] || { true;return 0;}
Upvotes: 8
Reputation: 4325
Not exactly asked for, but I use this to convert an OpenLDAP timestamp like 20241111073923Z
to seconds since the epoch:
echo $(date -u --date=$(echo "$1" | sed \
-e 's/^\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)Z$/\1-\2-\3T\4:\5:\6/') '+%s')
For the example timestamp the command executed will be date -u --date=2024-11-11T07:39:23 +%s
, and the output will be 1731310763
.
Upvotes: 0
Reputation: 7327
A lot of these answers are overly complicated and also are missing how to use variables. This is how you would do it more simply on standard Linux system (as previously mentioned the date command would have to be adjusted for Mac Users) :
Sample script:
#!/bin/bash
orig="Apr 28 07:50:01"
epoch=$(date -d "${orig}" +"%s")
epoch_to_date=$(date -d @$epoch +%Y%m%d_%H%M%S)
echo "RESULTS:"
echo "original = $orig"
echo "epoch conv = $epoch"
echo "epoch to human readable time stamp = $epoch_to_date"
Results in :
RESULTS:
original = Apr 28 07:50:01
epoch conv = 1524916201
epoch to human readable time stamp = 20180428_075001
Or as a function :
# -- Converts from human to epoch or epoch to human, specifically "Apr 28 07:50:01" human.
# typeset now=$(date +"%s")
# typeset now_human_date=$(convert_cron_time "human" "$now")
function convert_cron_time() {
case "${1,,}" in
epoch)
# human to epoch (eg. "Apr 28 07:50:01" to 1524916201)
echo $(date -d "${2}" +"%s")
;;
human)
# epoch to human (eg. 1524916201 to "Apr 28 07:50:01")
echo $(date -d "@${2}" +"%b %d %H:%M:%S")
;;
esac
}
Upvotes: 16
Reputation: 23513
I added the following alias to .bashrc
(or .zshrc
) - note the --utc
switch which converts the input as UTC time zone. You can remove it to use the local machine time zone but in my experience I usually want UTC for this:
alias datetoepoch='date --utc +%s -d'
Now I can just type in the terminal something like:
datetoepoch 2024-03-18
and get the result:
1710720000
Upvotes: 0
Reputation: 1571
For Linux, run this command:
date -d '06/12/2012 07:21:22' +"%s"
For macOS, run this command:
date -jf "%Y-%m-%d %H:%M:%S" "1970-01-01 00:00:00" +%s
Upvotes: 90
Reputation: 10572
Just be sure what timezone you want to use.
datetime="06/12/2012 07:21:22"
Most popular use takes machine timezone.
date -d "$datetime" +"%s" #depends on local timezone, my output = "1339456882"
But in case you intentionally want to pass UTC datetime and you want proper timezone you need to add -u
flag. Otherwise you convert it from your local timezone.
date -u -d "$datetime" +"%s" #general output = "1339485682"
Upvotes: 8
Reputation: 19286
What you're looking for is date --date='06/12/2012 07:21:22' +"%s"
. Keep in mind that this assumes you're using GNU coreutils, as both --date
and the %s
format string are GNU extensions. POSIX doesn't specify either of those, so there is no portable way of making such conversion even on POSIX compliant systems.
Consult the appropriate manual page for other versions of date
.
Note: bash --date
and -d
option expects the date in US or ISO8601 format, i.e. mm/dd/yyyy
or yyyy-mm-dd
, not in UK, EU, or any other format.
Upvotes: 130
Reputation: 49
get_curr_date () {
# get unix time
DATE=$(date +%s)
echo "DATE_CURR : "$DATE
}
conv_utime_hread () {
# convert unix time to human readable format
DATE_HREAD=$(date -d @$DATE +%Y%m%d_%H%M%S)
echo "DATE_HREAD : "$DATE_HREAD
}
Upvotes: 4