Comprehensive Reference Guide — Unix epoch, time differences, session tracking, and precise duration calculations
Unix epoch time is the number of seconds elapsed since January 1, 1970 00:00:00 UTC. It's the universal way to represent time in computing—perfect for calculating durations, comparing timestamps, and storing time data.
Simple Math: Duration = End Time - Start Time. No date parsing, no timezone headaches.
Universal: Works across systems, languages, and timezones.
Precise: Can include milliseconds or nanoseconds for high-precision timing.
Session duration tracking, performance benchmarking, log analysis, billing calculations, SLA monitoring, cache expiration, and any scenario where you need to measure elapsed time.
date +%s — Current epoch (seconds)
date +%s%N — Epoch with nanoseconds
date +%s%3N — Epoch with milliseconds
date -d @EPOCH — Convert epoch to human readable
date -d "STRING" +%s — Convert string to epoch
| Unit | Seconds | Calculation |
|---|---|---|
| 1 Minute | 60 | 60 |
| 1 Hour | 3,600 | 60 × 60 |
| 1 Day | 86,400 | 60 × 60 × 24 |
| 1 Week | 604,800 | 86,400 × 7 |
| 1 Year (avg) | 31,536,000 | 86,400 × 365 |
Getting current epoch time and converting between epoch and human-readable formats.
#!/bin/bash
# Basic epoch time operations
echo "=== Current Time as Epoch ==="
epoch=$(date +%s)
echo "Epoch seconds: $epoch"
echo "With milliseconds: $(date +%s%3N)"
echo "With microseconds: $(date +%s%6N)"
echo "With nanoseconds: $(date +%s%N)"
echo ""
echo "=== Epoch to Human Readable ==="
echo "Current epoch $epoch ="
echo " Local: $(date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " UTC: $(date -u -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " Full: $(date -d @$epoch)"
echo ""
echo "=== Human Readable to Epoch ==="
# Various input formats
echo "'2025-11-18 14:30:00' = $(date -d '2025-11-18 14:30:00' +%s)"
echo "'Nov 18, 2025 2:30pm' = $(date -d 'Nov 18, 2025 2:30pm' +%s)"
echo "'now' = $(date -d 'now' +%s)"
echo "'yesterday' = $(date -d 'yesterday' +%s)"
echo "'tomorrow noon' = $(date -d 'tomorrow noon' +%s)"
echo ""
echo "=== Specific Epochs ==="
echo "Epoch 0 = $(date -d @0 '+%Y-%m-%d %H:%M:%S %Z')"
echo "Epoch 1000000000 = $(date -d @1000000000 '+%Y-%m-%d %H:%M:%S %Z')"
echo "Epoch 2000000000 = $(date -d @2000000000 '+%Y-%m-%d %H:%M:%S %Z')"
echo ""
echo "=== Current Time Details ==="
echo "Epoch: $epoch"
echo "ISO 8601: $(date -d @$epoch '+%Y-%m-%dT%H:%M:%S%z')"
echo "RFC 2822: $(date -d @$epoch -R)"
The fundamental pattern: capture start time, do work, capture end time, calculate difference.
#!/bin/bash
# Simple duration calculation
echo "=== Basic Duration Pattern ==="
# Capture start time
start_epoch=$(date +%s)
echo "Started at: $(date -d @$start_epoch '+%H:%M:%S')"
# Simulate work
echo "Working..."
sleep 3
# Capture end time
end_epoch=$(date +%s)
echo "Ended at: $(date -d @$end_epoch '+%H:%M:%S')"
# Calculate duration
duration=$((end_epoch - start_epoch))
echo "Duration: $duration seconds"
echo ""
echo "=== Duration with Milliseconds ==="
start_ms=$(date +%s%3N)
sleep 1.5
end_ms=$(date +%s%3N)
duration_ms=$((end_ms - start_ms))
echo "Duration: $duration_ms milliseconds"
echo "Duration: $(echo "scale=3; $duration_ms / 1000" | bc) seconds"
echo ""
echo "=== Duration Between Two Dates ==="
# Calculate time between two specific dates
date1="2025-11-18 09:00:00"
date2="2025-11-18 17:30:00"
epoch1=$(date -d "$date1" +%s)
epoch2=$(date -d "$date2" +%s)
diff=$((epoch2 - epoch1))
echo "From: $date1"
echo "To: $date2"
echo ""
echo "Duration: $diff seconds"
echo " = $((diff / 60)) minutes"
echo " = $(echo "scale=2; $diff / 3600" | bc) hours"
Converting raw seconds into days, hours, minutes, and seconds format.
#!/bin/bash
# Convert seconds to human readable duration
# Function: seconds to readable format
seconds_to_human() {
local total_secs=$1
local days=$((total_secs / 86400))
local hours=$(( (total_secs % 86400) / 3600 ))
local mins=$(( (total_secs % 3600) / 60 ))
local secs=$((total_secs % 60))
if ((days > 0)); then
printf "%dd %02dh %02dm %02ds" $days $hours $mins $secs
elif ((hours > 0)); then
printf "%dh %02dm %02ds" $hours $mins $secs
elif ((mins > 0)); then
printf "%dm %02ds" $mins $secs
else
printf "%ds" $secs
fi
}
# Function: seconds to HH:MM:SS
seconds_to_hms() {
local total_secs=$1
local hours=$((total_secs / 3600))
local mins=$(( (total_secs % 3600) / 60 ))
local secs=$((total_secs % 60))
printf "%02d:%02d:%02d" $hours $mins $secs
}
# Function: seconds to verbose
seconds_to_verbose() {
local total_secs=$1
local days=$((total_secs / 86400))
local hours=$(( (total_secs % 86400) / 3600 ))
local mins=$(( (total_secs % 3600) / 60 ))
local secs=$((total_secs % 60))
local result=""
((days > 0)) && result+="$days day(s) "
((hours > 0)) && result+="$hours hour(s) "
((mins > 0)) && result+="$mins minute(s) "
((secs > 0)) && result+="$secs second(s)"
echo "${result:-0 seconds}"
}
echo "=== Test Various Durations ==="
test_values=(45 125 3661 7384 90061 186400)
printf "%-12s %-20s %-15s %s\n" "Seconds" "Human" "HH:MM:SS" "Verbose"
printf "%-12s %-20s %-15s %s\n" "-------" "-----" "--------" "-------"
for secs in "${test_values[@]}"; do
human=$(seconds_to_human $secs)
hms=$(seconds_to_hms $secs)
verbose=$(seconds_to_verbose $secs)
printf "%-12d %-20s %-15s %s\n" "$secs" "$human" "$hms" "$verbose"
done
echo ""
echo "=== Practical Example ==="
# Time someone was on a webpage
arrival="2025-11-18 10:23:17"
departure="2025-11-18 10:31:42"
start=$(date -d "$arrival" +%s)
end=$(date -d "$departure" +%s)
duration=$((end - start))
echo "Page session:"
echo " Arrived: $arrival"
echo " Left: $departure"
echo " Duration: $(seconds_to_human $duration) ($(seconds_to_hms $duration))"
Complete implementation for tracking how long someone spends on a page—exactly like your original scenario.
#!/bin/bash
# Web session duration tracking
# Simulate session data (in real life, from logs or database)
# Format: session_id|page|arrival_time|departure_time
sessions="
S001|/home|2025-11-18 09:15:23|2025-11-18 09:18:47
S002|/products|2025-11-18 09:20:01|2025-11-18 09:35:22
S003|/checkout|2025-11-18 09:36:05|2025-11-18 09:42:18
S004|/home|2025-11-18 10:01:00|2025-11-18 10:02:30
S005|/products|2025-11-18 10:15:45|2025-11-18 11:02:33
"
# Duration formatter
format_duration() {
local secs=$1
local mins=$((secs / 60))
local s=$((secs % 60))
printf "%d:%02d" $mins $s
}
echo "=== Session Duration Report ==="
echo ""
printf "%-8s %-12s %-10s %-10s %s\n" "Session" "Page" "Duration" "Seconds" "Status"
printf "%-8s %-12s %-10s %-10s %s\n" "-------" "----" "--------" "-------" "------"
total_time=0
session_count=0
while IFS='|' read -r sid page arrival departure; do
[[ -z "$sid" ]] && continue
# Convert to epoch
start_epoch=$(date -d "$arrival" +%s)
end_epoch=$(date -d "$departure" +%s)
# Calculate duration
duration=$((end_epoch - start_epoch))
((total_time += duration))
((session_count++))
# Determine status based on duration
if ((duration < 60)); then
status="Bounce"
elif ((duration < 300)); then
status="Short"
elif ((duration < 1800)); then
status="Normal"
else
status="Extended"
fi
# Format duration as M:SS
formatted=$(format_duration $duration)
printf "%-8s %-12s %-10s %-10d %s\n" "$sid" "$page" "$formatted" "$duration" "$status"
done <<< "$sessions"
echo ""
echo "=== Summary ==="
avg=$((total_time / session_count))
echo "Total sessions: $session_count"
echo "Total time: $(format_duration $total_time) ($total_time seconds)"
echo "Average session: $(format_duration $avg) ($avg seconds)"
echo ""
echo "=== Single Session Detail ==="
# Detailed breakdown for one session
arrival="2025-11-18 14:23:17"
departure="2025-11-18 14:31:42"
arr_epoch=$(date -d "$arrival" +%s)
dep_epoch=$(date -d "$departure" +%s)
dur_secs=$((dep_epoch - arr_epoch))
echo "Arrival: $arrival"
echo " Epoch: $arr_epoch"
echo ""
echo "Departure: $departure"
echo " Epoch: $dep_epoch"
echo ""
echo "Calculation: $dep_epoch - $arr_epoch = $dur_secs seconds"
echo ""
echo "Duration breakdown:"
echo " Total seconds: $dur_secs"
echo " Minutes: $((dur_secs / 60))"
echo " Remaining seconds: $((dur_secs % 60))"
echo " Formatted: $(format_duration $dur_secs)"
Millisecond and nanosecond precision for benchmarking and performance measurement.
#!/bin/bash
# High-precision timing
echo "=== Nanosecond Precision ==="
# Capture with nanoseconds
start_ns=$(date +%s%N)
# Simulate quick operation
for i in {1..10000}; do
echo "$i" > /dev/null
done
end_ns=$(date +%s%N)
# Calculate difference
diff_ns=$((end_ns - start_ns))
diff_ms=$((diff_ns / 1000000))
diff_us=$((diff_ns / 1000))
diff_s=$(echo "scale=6; $diff_ns / 1000000000" | bc)
echo "Start: $start_ns ns"
echo "End: $end_ns ns"
echo ""
echo "Duration: $diff_ns nanoseconds"
echo " $diff_us microseconds"
echo " $diff_ms milliseconds"
echo " $diff_s seconds"
echo ""
echo "=== Benchmark Function ==="
benchmark() {
local label="$1"
shift
local start=$(date +%s%N)
"$@"
local end=$(date +%s%N)
local elapsed_ms=$(( (end - start) / 1000000 ))
printf "%-30s %6d ms\n" "$label:" "$elapsed_ms"
}
# Test various operations
benchmark "Sleep 100ms" sleep 0.1
benchmark "Loop 10000" bash -c 'for i in {1..10000}; do :; done'
benchmark "Echo to /dev/null" bash -c 'for i in {1..1000}; do echo test > /dev/null; done'
echo ""
echo "=== Multiple Run Statistics ==="
runs=5
times=()
for ((i=1; i<=runs; i++)); do
start=$(date +%s%N)
# Operation to benchmark
for j in {1..5000}; do
echo "$j" > /dev/null
done
end=$(date +%s%N)
elapsed=$(( (end - start) / 1000 )) # microseconds
times+=($elapsed)
echo "Run $i: $elapsed µs"
done
# Calculate stats
total=0
min=${times[0]}
max=${times[0]}
for t in "${times[@]}"; do
((total += t))
((t < min)) && min=$t
((t > max)) && max=$t
done
avg=$((total / runs))
echo ""
echo "Statistics:"
echo " Min: $min µs"
echo " Max: $max µs"
echo " Avg: $avg µs"
Parsing log timestamps and calculating durations between events.
#!/bin/bash
# Log file time analysis
# Simulated log entries
log_data="2025-11-18 09:15:23 START Job_A
2025-11-18 09:15:45 START Job_B
2025-11-18 09:18:12 END Job_A
2025-11-18 09:22:31 END Job_B
2025-11-18 09:30:00 START Job_C
2025-11-18 09:45:17 END Job_C
2025-11-18 10:00:00 START Job_D
2025-11-18 10:02:30 END Job_D"
echo "=== Job Duration Analysis ==="
echo ""
declare -A start_times
# Process log entries
while read -r date time action job; do
timestamp="$date $time"
epoch=$(date -d "$timestamp" +%s)
if [[ "$action" == "START" ]]; then
start_times[$job]=$epoch
elif [[ "$action" == "END" ]]; then
if [[ -n "${start_times[$job]}" ]]; then
duration=$((epoch - start_times[$job]))
mins=$((duration / 60))
secs=$((duration % 60))
printf "%-8s Duration: %2d:%02d (%d seconds)\n" "$job" $mins $secs $duration
fi
fi
done <<< "$log_data"
echo ""
echo "=== Time Between Log Events ==="
# Calculate time gaps between consecutive entries
prev_epoch=""
prev_entry=""
while read -r date time rest; do
timestamp="$date $time"
epoch=$(date -d "$timestamp" +%s)
if [[ -n "$prev_epoch" ]]; then
gap=$((epoch - prev_epoch))
if ((gap > 60)); then
echo "Gap of ${gap}s between:"
echo " $prev_entry"
echo " $date $time $rest"
echo ""
fi
fi
prev_epoch=$epoch
prev_entry="$date $time $rest"
done <<< "$log_data"
echo "=== Apache Log Format Parsing ==="
# Apache common log format timestamp
apache_entry='192.168.1.100 - - [18/Nov/2025:14:30:45 -0500] "GET /page HTTP/1.1" 200 1234'
# Extract and parse timestamp
timestamp=$(echo "$apache_entry" | grep -oP '\[\K[^\]]+')
# Convert Apache format to parseable format
parsed_time=$(echo "$timestamp" | sed 's/:/ /' | sed 's/\// /g')
epoch=$(date -d "$parsed_time" +%s 2>/dev/null)
echo "Apache log: $apache_entry"
echo "Timestamp: $timestamp"
echo "Epoch: $epoch"
Calculating if operations meet SLA requirements and implementing timeout logic.
#!/bin/bash
# SLA and timeout monitoring
echo "=== SLA Compliance Check ==="
# SLA thresholds (in seconds)
SLA_WARNING=30
SLA_CRITICAL=60
SLA_BREACH=120
# Simulated response times
responses=(15 28 45 62 95 180 22 31)
passed=0
warning=0
critical=0
breach=0
for response in "${responses[@]}"; do
if ((response <= SLA_WARNING)); then
status="✓ PASS"
((passed++))
elif ((response <= SLA_CRITICAL)); then
status="⚠ WARNING"
((warning++))
elif ((response <= SLA_BREACH)); then
status="✗ CRITICAL"
((critical++))
else
status="✗✗ BREACH"
((breach++))
fi
printf "Response: %3ds - %s\n" $response "$status"
done
echo ""
echo "Summary:"
echo " Passed: $passed"
echo " Warning: $warning"
echo " Critical: $critical"
echo " Breach: $breach"
compliance=$(echo "scale=1; ($passed * 100) / ${#responses[@]}" | bc)
echo " SLA Compliance: ${compliance}%"
echo ""
echo "=== Timeout Implementation ==="
run_with_timeout() {
local timeout=$1
local cmd="$2"
local start=$(date +%s)
# Run command in background
eval "$cmd" &
local pid=$!
# Check periodically
while kill -0 $pid 2>/dev/null; do
local elapsed=$(($(date +%s) - start))
if ((elapsed >= timeout)); then
kill $pid 2>/dev/null
echo "TIMEOUT after ${timeout}s"
return 1
fi
sleep 0.1
done
wait $pid
local exit_code=$?
local elapsed=$(($(date +%s) - start))
echo "Completed in ${elapsed}s (exit: $exit_code)"
return $exit_code
}
echo "Running with 2s timeout:"
run_with_timeout 2 "sleep 1"
echo ""
echo "Running with 2s timeout (will timeout):"
run_with_timeout 2 "sleep 5"
echo ""
echo "=== Deadline Calculation ==="
# Calculate if we'll meet a deadline
deadline="2025-11-18 17:00:00"
deadline_epoch=$(date -d "$deadline" +%s)
now_epoch=$(date +%s)
remaining=$((deadline_epoch - now_epoch))
if ((remaining > 0)); then
hours=$((remaining / 3600))
mins=$(( (remaining % 3600) / 60 ))
echo "Deadline: $deadline"
echo "Time remaining: ${hours}h ${mins}m"
if ((remaining < 3600)); then
echo "⚠ WARNING: Less than 1 hour remaining!"
fi
else
overdue=$((-remaining))
echo "✗ DEADLINE MISSED by $((overdue / 60)) minutes"
fi
Calculating charges based on time usage—perfect for cloud resources, consulting, parking, etc.
#!/bin/bash
# Time-based billing calculations
echo "=== Hourly Billing ==="
# Usage records: start|end|resource
usage="
2025-11-18 08:15:00|2025-11-18 12:30:00|VM-Large
2025-11-18 09:00:00|2025-11-18 11:45:00|VM-Small
2025-11-18 10:30:00|2025-11-18 18:00:00|VM-Large
2025-11-18 14:00:00|2025-11-18 14:45:00|VM-Small
"
# Rates per hour
declare -A rates
rates["VM-Large"]=0.50
rates["VM-Small"]=0.15
total_cost=0
printf "%-12s %-8s %-10s %s\n" "Resource" "Hours" "Rate" "Cost"
printf "%-12s %-8s %-10s %s\n" "--------" "-----" "----" "----"
while IFS='|' read -r start end resource; do
[[ -z "$start" ]] && continue
start_epoch=$(date -d "$start" +%s)
end_epoch=$(date -d "$end" +%s)
duration_secs=$((end_epoch - start_epoch))
duration_hours=$(echo "scale=2; $duration_secs / 3600" | bc)
rate=${rates[$resource]}
cost=$(echo "scale=2; $duration_hours * $rate" | bc)
total_cost=$(echo "scale=2; $total_cost + $cost" | bc)
printf "%-12s %-8s \$%-9s \$%s\n" "$resource" "$duration_hours" "$rate/hr" "$cost"
done <<< "$usage"
echo ""
printf "%-12s %-8s %-10s \$%s\n" "TOTAL" "" "" "$total_cost"
echo ""
echo "=== Parking Meter Calculation ==="
# $2 per hour, minimum 30 minutes, maximum 4 hours
arrival="2025-11-18 10:23:00"
departure="2025-11-18 13:47:00"
start=$(date -d "$arrival" +%s)
end=$(date -d "$departure" +%s)
duration=$((end - start))
# Round up to nearest 30 minutes
half_hours=$(( (duration + 1799) / 1800 ))
hours=$(echo "scale=1; $half_hours / 2" | bc)
# Calculate charge ($2/hour)
charge=$(echo "scale=2; $hours * 2" | bc)
echo "Arrived: $arrival"
echo "Left: $departure"
echo "Duration: $((duration / 60)) minutes"
echo "Billable: $hours hours"
echo "Charge: \$$charge"
echo ""
echo "=== Consulting Time Tracker ==="
# Track billable time with different rates
declare -A client_time
declare -A client_rate
client_rate["ClientA"]=150
client_rate["ClientB"]=125
client_rate["ClientC"]=175
# Simulated time entries (minutes)
client_time["ClientA"]=245
client_time["ClientB"]=180
client_time["ClientC"]=90
echo "Billable Hours Report"
echo ""
printf "%-10s %-8s %-10s %s\n" "Client" "Hours" "Rate" "Amount"
printf "%-10s %-8s %-10s %s\n" "------" "-----" "----" "------"
grand_total=0
for client in "${!client_time[@]}"; do
mins=${client_time[$client]}
hours=$(echo "scale=2; $mins / 60" | bc)
rate=${client_rate[$client]}
amount=$(echo "scale=2; $hours * $rate" | bc)
grand_total=$(echo "scale=2; $grand_total + $amount" | bc)
printf "%-10s %-8s \$%-9s \$%s\n" "$client" "$hours" "$rate/hr" "$amount"
done
echo ""
printf "%-10s %-8s %-10s \$%s\n" "TOTAL" "" "" "$grand_total"
Handling epoch conversions across timezones—critical for distributed systems and global operations.
#!/bin/bash
# Epoch time and timezone handling
echo "=== Epoch is Timezone-Independent ==="
# Same epoch = same moment in time
epoch=1731945045
echo "Epoch: $epoch"
echo ""
echo "This moment in different timezones:"
echo " UTC: $(TZ=UTC date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " Eastern: $(TZ=America/New_York date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " Pacific: $(TZ=America/Los_Angeles date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " London: $(TZ=Europe/London date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo " Tokyo: $(TZ=Asia/Tokyo date -d @$epoch '+%Y-%m-%d %H:%M:%S %Z')"
echo ""
echo "=== Convert Local Time to Epoch ==="
# When converting TO epoch, timezone matters
local_time="2025-11-18 14:00:00"
echo "Time string: '$local_time'"
echo ""
echo "Interpreted in different zones:"
for tz in "America/New_York" "America/Los_Angeles" "UTC" "Asia/Tokyo"; do
epoch=$(TZ=$tz date -d "$local_time" +%s)
echo " $tz: $epoch"
done
echo ""
echo "=== Calculate Duration Across Timezones ==="
# Meeting: 2pm Eastern to 4pm Eastern
# What's the duration for someone in Tokyo?
meeting_start="2025-11-18 14:00:00"
meeting_end="2025-11-18 16:00:00"
# Convert to epoch (in Eastern time)
start_epoch=$(TZ=America/New_York date -d "$meeting_start" +%s)
end_epoch=$(TZ=America/New_York date -d "$meeting_end" +%s)
duration=$((end_epoch - start_epoch))
echo "Meeting (Eastern): $meeting_start to $meeting_end"
echo "Duration: $((duration / 60)) minutes"
echo ""
echo "In Tokyo time:"
echo " Start: $(TZ=Asia/Tokyo date -d @$start_epoch '+%Y-%m-%d %H:%M %Z')"
echo " End: $(TZ=Asia/Tokyo date -d @$end_epoch '+%Y-%m-%d %H:%M %Z')"
echo " (Same duration: $((duration / 60)) minutes)"
echo ""
echo "=== Global Event Countdown ==="
# Event at specific UTC time
event_utc="2025-12-01 00:00:00 UTC"
event_epoch=$(date -d "$event_utc" +%s)
now_epoch=$(date +%s)
remaining=$((event_epoch - now_epoch))
days=$((remaining / 86400))
hours=$(( (remaining % 86400) / 3600 ))
echo "Event: $event_utc"
echo "Countdown: ${days}d ${hours}h"
echo ""
echo "Event time in various zones:"
for tz in "America/New_York" "America/Los_Angeles" "Europe/London" "Asia/Tokyo"; do
local_time=$(TZ=$tz date -d @$event_epoch '+%Y-%m-%d %H:%M %Z')
city=$(echo $tz | cut -d'/' -f2)
printf " %-15s %s\n" "$city:" "$local_time"
done
A reusable library of functions for epoch time and duration calculations.
#!/bin/bash
# Complete epoch time and duration library
#######################################
# EPOCH CONVERSION FUNCTIONS
#######################################
# Get current epoch (seconds)
now_epoch() {
date +%s
}
# Get current epoch (milliseconds)
now_ms() {
date +%s%3N
}
# Get current epoch (nanoseconds)
now_ns() {
date +%s%N
}
# Convert date string to epoch
to_epoch() {
date -d "$1" +%s
}
# Convert epoch to date string
from_epoch() {
local format="${2:-%Y-%m-%d %H:%M:%S}"
date -d @$1 "+$format"
}
#######################################
# DURATION CALCULATION FUNCTIONS
#######################################
# Calculate duration between two epochs
duration() {
echo $(($2 - $1))
}
# Calculate duration between two date strings
duration_between() {
local start=$(to_epoch "$1")
local end=$(to_epoch "$2")
echo $((end - start))
}
#######################################
# DURATION FORMATTING FUNCTIONS
#######################################
# Seconds to HH:MM:SS
to_hms() {
local secs=$1
printf "%02d:%02d:%02d" $((secs/3600)) $(((secs%3600)/60)) $((secs%60))
}
# Seconds to human readable
to_human() {
local secs=$1
local d=$((secs/86400)) h=$(((secs%86400)/3600))
local m=$(((secs%3600)/60)) s=$((secs%60))
((d>0)) && printf "%dd " $d
((h>0)) && printf "%dh " $h
((m>0)) && printf "%dm " $m
printf "%ds" $s
}
# Seconds to short format (Xm Ys)
to_short() {
local secs=$1
if ((secs >= 3600)); then
printf "%dh %dm" $((secs/3600)) $(((secs%3600)/60))
elif ((secs >= 60)); then
printf "%dm %ds" $((secs/60)) $((secs%60))
else
printf "%ds" $secs
fi
}
#######################################
# TIMER FUNCTIONS
#######################################
# Start a named timer
timer_start() {
eval "TIMER_$1=$(now_ms)"
}
# Get elapsed time for named timer (ms)
timer_elapsed() {
local start_var="TIMER_$1"
local start=${!start_var}
echo $(($(now_ms) - start))
}
# Stop timer and return formatted duration
timer_stop() {
local ms=$(timer_elapsed $1)
if ((ms >= 1000)); then
echo "$(echo "scale=2; $ms/1000" | bc)s"
else
echo "${ms}ms"
fi
}
#######################################
# DEMO
#######################################
echo "===== Epoch Time Library Demo ====="
echo ""
echo "Current time:"
echo " Epoch (s): $(now_epoch)"
echo " Epoch (ms): $(now_ms)"
echo " Formatted: $(from_epoch $(now_epoch))"
echo ""
echo "Conversions:"
echo " String to epoch: $(to_epoch '2025-11-18 14:30:00')"
echo " Epoch to string: $(from_epoch 1731945000)"
echo " Custom format: $(from_epoch 1731945000 '%A, %B %d')"
echo ""
echo "Duration calculations:"
dur=$(duration_between "2025-11-18 09:00:00" "2025-11-18 17:30:00")
echo " 9 AM to 5:30 PM = $dur seconds"
echo " As HH:MM:SS: $(to_hms $dur)"
echo " Human readable: $(to_human $dur)"
echo " Short format: $(to_short $dur)"
echo ""
echo "Timer demo:"
timer_start "demo"
sleep 0.5
echo " After 500ms: $(timer_stop demo)"
timer_start "work"
for i in {1..10000}; do :; done
echo " Loop 10000: $(timer_stop work)"
echo ""
echo "Format examples:"
for secs in 45 125 3661 90061; do
printf " %6d sec = %-12s = %-15s = %s\n" \
$secs "$(to_short $secs)" "$(to_human $secs)" "$(to_hms $secs)"
done
echo ""
echo "===== End Demo ====="
# Get current epoch
epoch=$(date +%s)
# Convert to epoch
epoch=$(date -d "2025-11-18 14:30:00" +%s)
# Convert from epoch
date -d @1731945000 '+%Y-%m-%d %H:%M:%S'
# Calculate duration
duration=$((end_epoch - start_epoch))
# Duration to minutes:seconds
mins=$((duration / 60))
secs=$((duration % 60))
printf "%d:%02d" $mins $secs
# Duration to hours:minutes:seconds
printf "%02d:%02d:%02d" $((dur/3600)) $(((dur%3600)/60)) $((dur%60))
| Task | Code |
|---|---|
| Time an operation | start=$(date +%s); work; echo $(($(date +%s) - start))s |
| Check if expired | (($(date +%s) > expiry_epoch)) && echo "Expired" |
| Add time to epoch | future=$((epoch + 3600)) # +1 hour |
| Subtract time | past=$((epoch - 86400)) # -1 day |
| High precision | ms=$(date +%s%3N) |
| UTC epoch | date -u +%s (same as local) |