Files
log/tools/report-range.sh
jiantw83 e6fafd4132 feat(report): 新增工作日誌總結技能
What: 新增 jsc-log:report,把工作日誌總結成年報、月報、週報或日報,寫進 wiki REPORT_{HASH}。另加 tools/report-range.sh 算期間、tools/report-template.sh 解析範本,以及四份報表範本與報表目錄範本。
Why: worklog 只記單筆工作,累積起來沒有工具看得出一週或一個月做了什麼、什麼在卡。要總結只能自己翻頁面加總。
How: 期間換算交給系統的 date,不自己算閏年與週界;週次採 ISO-8601。範本解析採工作目錄優先,.jsc/templates/report-{period}.md 蓋過技能自帶的那份,專案要換格式不必改技能。資料讀 LOG_CONTENTS 列出的所有日誌頁,取工作日期落在期間內的條目,只加總條目真的寫了的數字。
Who: 工作日誌的期間總結。
2026-08-26 10:47:07 +08:00

76 lines
2.6 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env sh
# report-range.sh — 算出報表期間的起訖日期與標籤(供 jsc-log:report 呼叫)。
# 用法:
# report-range.sh {daily|weekly|monthly|yearly} [基準日期 yyyy-MM-dd]
# 基準日期省略時用今天。輸出一行 TSV:
# {start}<TAB>{end}<TAB>{label}<TAB>{period}
# start、end 皆為 yyyy-MM-dd,含頭含尾。
# label:daily=2026-08-26、weekly=2026-W35、monthly=2026-08、yearly=2026
#
# 週的定義採 ISO-8601:週一起算、週日結束,標籤用 ISO 週次。worklog 頁內以工作週的
# 週五整理內容,週次與那個週五落在同一週,兩邊對得起來。
#
# 日期運算優先用 GNU date -d,退回 BSD date -v。兩者都不支援就 exit 4,不自己算閏年:
# 手刻日期運算出錯的方式很安靜,報表會少算一天而沒有人發現。
#
# 結束碼: 0=成功 2=用法錯誤 4=系統的 date 不支援日期運算
set -eu
usage() {
echo "用法:report-range.sh {daily|weekly|monthly|yearly} [yyyy-MM-dd]" >&2
exit 2
}
period="${1:-}"
case "$period" in daily|weekly|monthly|yearly) ;; *) usage ;; esac
base="${2:-}"
if [ -z "$base" ]; then
base=$(date +%Y-%m-%d)
else
case "$base" in
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;;
*) echo "基準日期格式要是 yyyy-MM-dd:$base" >&2; exit 2 ;;
esac
fi
# $1=基準日 $2=偏移(例 -3 days、+1 month)$3=輸出格式
shift_date() {
if date -d "$1 $2" "+$3" >/dev/null 2>&1; then
date -d "$1 $2" "+$3"
return 0
fi
# BSD:偏移寫法不同(-v-3d),只轉換這裡真的用到的幾種
_bsd=$(printf '%s' "$2" | sed 's/ days\{0,1\}/d/; s/ months\{0,1\}/m/; s/ years\{0,1\}/y/; s/^+/+/')
if date -j -f %Y-%m-%d -v"$_bsd" "$1" "+$3" >/dev/null 2>&1; then
date -j -f %Y-%m-%d -v"$_bsd" "$1" "+$3"
return 0
fi
echo "系統的 date 不支援日期運算,算不出報表期間" >&2
exit 4
}
fmt() { shift_date "$1" "+0 days" "$2"; }
case "$period" in
daily)
start="$base"; end="$base"
label=$(fmt "$base" %Y-%m-%d) ;;
weekly)
# ISO 週:週一為第 1 天。%u 給 1(週一)到 7(週日)。
dow=$(fmt "$base" %u)
start=$(shift_date "$base" "-$((dow - 1)) days" %Y-%m-%d)
end=$(shift_date "$start" "+6 days" %Y-%m-%d)
label=$(fmt "$base" %G-W%V) ;;
monthly)
start=$(fmt "$base" %Y-%m-01)
end=$(shift_date "$(shift_date "$start" "+1 month" %Y-%m-%d)" "-1 day" %Y-%m-%d)
label=$(fmt "$base" %Y-%m) ;;
yearly)
start=$(fmt "$base" %Y-01-01)
end=$(fmt "$base" %Y-12-31)
label=$(fmt "$base" %Y) ;;
esac
printf '%s\t%s\t%s\t%s\n' "$start" "$end" "$label" "$period"