When using zsh, you may sometimes want to check:
- When a command was executed
- When it finished, and how long it took
This article summarizes methods to record timing information directly in your terminal using the following two mechanisms:
- Record the execution timestamp in your prompt each time you press
Enter - Automatically measure execution duration of commands and notify only when they take a long time
Enter timing: Record the execution timestamp in the prompt #
Add the following code to your ~/.zshrc:
function _date_exec {
PROMPT="[%D{%Y/%m/%d} %*] %~ %# "
zle .reset-prompt
zle .accept-line
}
zle -N accept-line _date_execHow it works #
- Press
Enter - The prompt is updated to a specified format (prefixing the timestamp at the left)
- The typed command is executed immediately afterward
Example #
[2025/12/30 12:46:54] ~ % cd scripts
[2025/12/30 12:46:57] ~ % git pullNow, simply scrolling the terminal history allows you to check when each command was executed.
Note: if you already customize your PROMPT
#
_date_exec overwrites the prompt earch time.
If you have an existing prompt configuration, merge it into _date_exec to avoid losing it.
Example:
# Existing PROMPT (example)
PROMPT="%n@%m:%~ %# "
# Merged prompt in _date_exec (timestamp + existing prompt)
function _date_exec {
PROMPT="[%D{%Y/%m/%d} %*] %n@%m:%~ %# "
zle .reset-prompt
zle .accept-line
}Measure execution time and notify when it takes long #
Add the following to your ~/.zshrc:
function format_duration() {
local total_seconds=$1
local hours=$(( total_seconds / 3600 ))
local minutes=$(( (total_seconds % 3600) / 60 ))
local seconds=$(( total_seconds % 60 ))
if (( hours > 0 )); then
echo "${hours}h ${minutes}m ${seconds}s"
elif (( minutes > 0 )); then
echo "${minutes}m ${seconds}s"
else
echo "${seconds}s"
fi
}
function _time_and_date_precmd() {
local timer_end=$SECONDS
local duration=$(( timer_end - TIMER_START ))
local current_time=$(date +"%Y-%m-%d %H:%M:%S")
if [[ -n "$TIMER_START" && "$duration" -gt 300 ]]; then
local formatted_duration=$(format_duration $duration)
printf "\nCommand finished at %s, took %s\n" "$current_time" "$formatted_duration"
fi
TIMER_START=""
}
function _time_and_date_preexec() {
TIMER_START=$SECONDS
}
add-zsh-hook preexec _time_and_date_preexec
add-zsh-hook precmd _time_and_date_precmdHow it works #
- Run any command (pressing
Entertriggerspreexec) preexecrecords the start time inTIMER_START- When command execution finishes,
precmdis called and calculates duration - If execution time is over 5 minutes (300 seconds), notify with start time, end time, and duration
- Reset
TIMER_STARTto prepare for the next command
Example #
[2025/12/30 10:35:22] ~ % make
Command finished at 2025-12-30 12:46:35, took 2h 11m 13sEven if you step away from the terminal, you can later check when the command started, when it finished, and how long it took just by looking at the terminal buffer.