Shell time comparisons
June 13, 2014
Applying an operation based on datetime
I just received a question today from a scientist asking how to apply some operation to particular files that fall within some temporal range.
I whipped up a quick example where I convert timestamps to UNIX integer time values (seconds since 1970-01-01 00:00:00) and compare them, then apply some operation.
# Some dummy times.
TIMESTAMPS=$(echo 2010-01-{10..11}T{01..11}:00:00)
STARTTIME=1263074400 # Start somewhere after the begining
STOPTIME=1263160800 # End before the last time
for TIMESTAMP in ${TIMESTAMPS}; do # Loop over all TIMESTAMPS
UNIXTIME=$(date -d"${TIMESTAMP}" +%s) # Convert timestamp string to integer
# Test if current timestamp is within target range
if [[ $UNIXTIME -gt $STARTTIME && $UNIXTIME -lt $STOPTIME ]]; then
echo "Process file"
else
echo "File outside range, do nothing"
fi
done
Breaking it down
We use shell expansion notation to give us a list of dummy timestamps for testing purposes:
TIMESTAMPS=$(echo 2010-01-{10..11}T{01..11}:00:00)
echo $TIMESTAMPS
2010-01-10T1:00:00 2010-01-10T2:00:00 2010-01-10T3:00:00 2010-01-10T4:00:00 2010-01-10T5:00:00 2010-01-10T6:00:00 2010-01-10T7:00:00 2010-01-10T8:00:00 2010-01-10T9:00:00 2010-01-10T10:00:00 2010-01-10T11:00:00 2010-01-11T1:00:00 2010-01-11T2:00:00 2010-01-11T3:00:00 2010-01-11T4:00:00 2010-01-11T5:00:00 2010-01-11T6:00:00 2010-01-11T7:00:00 2010-01-11T8:00:00 2010-01-11T9:00:00 2010-01-11T10:00:00 2010-01-11T11:00:00
Then we get the UNIX time epoch for the start and stop time:
date -d"2010-01-10T5:00:00" +%s
date -d"2010-01-11T5:00:00" +%s
Now we loop over all TIMESTAMPS:
for TIMESTAMP in ${TIMESTAMPS}; do # Loop over all TIMESTAMPS
## DO work in here
done
Inside the loop we convert the ISO time to a UNIX epoch time:
UNIXTIME=$(date -d"${TIMESTAMP}" +%s) # Convert timestamp string to integer
Then test to see if the value is in the range of start - stop time:
if [[ $UNIXTIME -gt $STARTTIME && $UNIXTIME -lt $STOPTIME ]]; then
echo "Process file"
else
echo "File outside range, do nothing"
fi
Output:
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
Process file
Process file
Process file
Process file
Process file
Process file
Process file
Process file
Process file
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
File outside range, do nothing
Tasking this a bit further and refactoring:
We define a function that operates on our timestamps
dotask() {
TS=$1
echo "Process file, $TS"
}
We define a function which takes a list of times, a start and stop time and applys some function to things that fall within the start and stop times.
applywithin() {
## Apply some program/task within a temporal range
TIMESTAMPS=$1
STARTTIME=$2
STOPTIME=$3
TASK=$4
for TIMESTAMP in ${TIMESTAMPS}; do # Loop over all TIMESTAMPS
UNIXTIME=$(date -d"${TIMESTAMP}" +%s) # Convert timestamp string to integer
# Test if current timestamp is within target range
if [[ $UNIXTIME -gt $STARTTIME && $UNIXTIME -lt $STOPTIME ]]; then
$TASK $TIMESTAMP
else
echo "File outside range, doing nothing"
fi
done
}
TIMESTAMPS=$(echo 2010-01-{10..11}T{01..11}:00:00)
applywithin $TIMESTAMPS 1263074400 1263160800 dotask
Now we can apply any operation we want based on each timestamp.
comments powered by Disqus