Last active
August 31, 2025 00:35
-
-
Save nicholaslythall/64c7a241b10c3dd0d9d607c2e14746c8 to your computer and use it in GitHub Desktop.
Calculate how long and when you've been at your computer today.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| # ANSI color codes | |
| GREEN="\033[0;32m" | |
| RED="\033[0;31m" | |
| BLUE="\033[0;34m" | |
| GREY="\033[0;90m" | |
| YELLOW="\033[0;33m" | |
| MAGENTA="\033[0;35m" | |
| BOLDWHITE="\033[1;37m" | |
| RESET="\033[0m" | |
| # Default to current day | |
| date_filter="$(date "+%Y-%m-%d")" | |
| # Parse aguments | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -y|--yesterday) | |
| date_filter="$(date -v-1d "+%Y-%m-%d")" | |
| shift | |
| ;; | |
| -d|--date) | |
| if [[ -n "$2" ]]; then | |
| date_filter="$2" | |
| shift 2 | |
| else | |
| echo "Error: --date requires and argument" >&2 | |
| exit 1 | |
| fi | |
| ;; | |
| *) | |
| echo "Unknown option: $1" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| # Check for -y or --yesterday flag | |
| if [[ "$1" == "-y" || "$1" == "--yesterday" ]]; then | |
| date_filter="$(date -v-1d "+%Y-%m-%d")" | |
| fi | |
| # Fetch the log for the current day | |
| log=$(pmset -g log | grep "$date_filter" | grep -e "Display is turned off" -e "Display is turned on") | |
| # Initialize variables | |
| previous_on_time="" | |
| previous_off_time="" | |
| total_minutes=0 | |
| while IFS= read -r line; do | |
| line=$(echo "$line" | sed 's/[[:space:]]*$//') | |
| timestamp=$(echo "$line" | awk '{print $1, $2}') | |
| timestamp_short=$(echo "$timestamp" | cut -c1-16) | |
| event=$(echo "$line" | grep -o "Display is turned \S*") | |
| if [[ "$event" == "Display is turned on" ]]; then | |
| # If there was a previous off event, calculate break time | |
| if [[ -n "$previous_off_time" ]]; then | |
| off_epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$previous_off_time" +"%s" 2>/dev/null) | |
| on_epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$timestamp" +"%s" 2>/dev/null) | |
| if [[ -n "$off_epoch" && -n "$on_epoch" ]]; then | |
| break_minutes=$(( (on_epoch - off_epoch) / 60 )) | |
| echo -e "${GREY}-- Break for $break_minutes minutes --${RESET}" | |
| fi | |
| fi | |
| echo -e "${GREEN}$timestamp_short Display turned on${RESET}" | |
| previous_on_time="$timestamp" | |
| previous_off_time="" | |
| elif [[ "$event" == "Display is turned off" ]]; then | |
| if [[ -n "$previous_on_time" ]]; then | |
| on_epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$previous_on_time" +"%s" 2>/dev/null) | |
| off_epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$timestamp" +"%s" 2>/dev/null) | |
| if [[ -n "$on_epoch" && -n "$off_epoch" ]]; then | |
| duration=$(( (off_epoch - on_epoch) / 60 )) | |
| echo -e "${RED}$timestamp_short Display turned off${MAGENTA} (was on for $duration minutes)${RESET}" | |
| total_minutes=$((total_minutes + duration)) | |
| else | |
| echo -e "${RED}$timestamp_short Display turned off${RESET}" | |
| fi | |
| else | |
| echo -e "${RED}$timestamp_short Display turned off${RESET}" | |
| fi | |
| previous_on_time="" | |
| previous_off_time="$timestamp" | |
| fi | |
| done <<< "$log" | |
| # Handle final unmatched "on" event (display is still on) | |
| if [[ -n "$previous_on_time" ]]; then | |
| now_epoch=$(date +"%s") | |
| on_epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$previous_on_time" +"%s" 2>/dev/null) | |
| if [[ -n "$on_epoch" ]]; then | |
| duration=$(( (now_epoch - on_epoch) / 60 )) | |
| now_short=$(date "+%Y-%m-%d %H:%M") | |
| echo -e "${GREEN}$now_short Displays still on ${MAGENTA}(was on for $duration minutes so far)${RESET}" | |
| total_minutes=$((total_minutes + duration)) | |
| fi | |
| fi | |
| total_part_hours=$(( total_minutes / 60 )) | |
| total_part_minutes=$(( total_minutes % 60 )) | |
| # Fractional hours (e.g. 1.23) | |
| total_hours=$(awk "BEGIN { printf \"%.2f\", $total_minutes/60 }") | |
| echo -e "\n${BOLDWHITE}Total Time Today: ${total_hours}hrs (${total_part_hours}hr and ${total_part_minutes} minutes)${RESET}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment