date: get current 15 minute interval
You can get the current unix timestamp with date "+%s"
, find the current quarter-hour with some simple math (my example is in bash
) and print it back with a better format with date
:
curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"
The @
syntax to set the current date and time from a timestamp is a GNU extention to date, if it don't works on your OS, you can do the same like this (don't forget to specify UTC, otherwise, it won't work) :
date -d"1970-01-01 $curquarter seconds UTC"
The following methods make it unnecessary to call date
twice.
A system call's overhead can make a "simple" command 100 times slower than bash doing the same thing in its own local environment.
UPDATE Just a quick mention about my above comment: "100 times slower". It can now read "500 times slower"... I recently fell (no, walked blindly) into this very issue. here is the link: Fast way to build a test file
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
or
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M
Both versions will return only
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Here is the first one with a TEST loop for all 60 values {00..59}
for X in {00..59} ; ###### TEST
do ###### TEST
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
M=$X ###### TEST
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
done ###### TEST
Here's a way to work on dates in the shell. First call date
to get the components, and fill the positional parameters ($1
, $2
, etc) with the components (note that this is one of these rare cases where you do want to use $(…)
outside of double quotes, to break the string into words). Then perform arithmetics, tests, or whatever you need to do on the components. Finally assemble the components.
The arithmetic part can be a little tricky because shells treat 0
as an octal prefix; for example here $(($5/15))
would fail at 8 or 9 minutes past the hour. Since there's at most one leading 0
, ${5#0}
is safe for arithmetic. Adding 100 and subsequently stripping the 1
is a way to get a fixed number of digits in the output.
set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"