Created
April 25, 2024 13:49
-
-
Save suzuki-kei/cd1b84e56af718fae4d6cd6d07d9ae0e to your computer and use it in GitHub Desktop.
work-time
This file contains 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
#!/usr/bin/env bash | |
set -eu -o posix -o pipefail | |
shopt -s extglob | |
declare -gr EXIT_STATUS_SUCCESS=0 | |
declare -gr EXIT_STATUS_NO_ARGUMENTS=1 | |
declare -gr EXIT_STATUS_INVALID_FORMAT=2 | |
declare -gr STANDARD_BREAK_TIME_IN_MINUTES=60 | |
declare -gr USAGE=$(cat <<EOS | sed 's/^ //' | |
NAME | |
$(basename -- "${0}") -- 一日の労働時間を計算します | |
SYNOPSIS | |
$(basename -- "${0}") [OPTION...] [TERM|BREAK_TIME]... | |
DESCRIPTION | |
勤務の開始時間, 終了時間, 休憩時間から一日の労働時間を計算します. | |
TERM | |
勤務の開始時間と終了時間を指定します. | |
有効な形式は "HH:MM-HH:MM" または "HHMM-HHMM" です (例: "09:00-18:00", "0900-1800"). | |
BREAK_TIME | |
途中休憩した時間 (昼休憩以外の休憩時間) を分単位で指定します. | |
有効な形式は "-M" です (例: "-30"). | |
OPTIONS | |
-h | --help | |
このコマンドの使い方を表示します. | |
EXAMPLES | |
# 勤務の開始時間と終了時間を指定します | |
$ $(basename -- "${0}") 09:00-18:00 | |
# 途中休憩した場合は以下のように働いた時間帯を指定します | |
$ $(basename -- "${0}") 09:00-18:00 19:00-20:00 | |
# 次のように途中休憩の時間を指定しても同じ結果になります | |
$ $(basename -- "${0}") 09:00-20:00 -60 | |
EOS | |
) | |
function main | |
{ | |
if [[ $# == 0 ]]; then | |
print_usage | |
exit ${EXIT_STATUS_NO_ARGUMENTS} | |
fi | |
declare work_time_in_minutes=-${STANDARD_BREAK_TIME_IN_MINUTES} | |
declare break_time_in_minutes=0 | |
for argument in "$@"; do | |
if [[ "${argument}" == '-h' ]] || [[ "${argument}" == '--help' ]]; then | |
print_usage | |
exit ${EXIT_STATUS_SUCCESS} | |
fi | |
# 正式には HH:MM-HH:MM 形式と HHMM-HHMM 形式を認める. | |
# ただし, ゼロ埋めしない形式 (H:MM や HH:M など) も明文化しない機能として許容する. | |
if [[ "${argument}" =~ ^([0-9][0-9]?):?([0-9][0-9]?)-([0-9][0-9]?):?([0-9][0-9]?)$ ]]; then | |
declare lower=$(echo "${BASH_REMATCH[1]} * 60 + ${BASH_REMATCH[2]}" | bc) | |
declare upper=$(echo "${BASH_REMATCH[3]} * 60 + ${BASH_REMATCH[4]}" | bc) | |
if [[ ${lower} -gt ${upper} ]]; then | |
upper=$((upper + 24 * 60)) | |
fi | |
work_time_in_minutes=$((work_time_in_minutes + (upper - lower))) | |
continue | |
fi | |
if [[ "${argument}" =~ ^-([0-9]+)$ ]]; then | |
work_time_in_minutes=$((work_time_in_minutes - BASH_REMATCH[1])) | |
break_time_in_minutes=$((break_time_in_minutes + BASH_REMATCH[1])) | |
continue | |
fi | |
echo "Invalid argument: ${argument}" >&2 | |
exit ${EXIT_STATUS_INVALID_FORMAT} | |
done | |
declare -r hours=$((work_time_in_minutes / 60)) | |
declare -r minutes=$((work_time_in_minutes % 60)) | |
declare -r work_time="${hours}$(echo "${minutes} / 60" | bc -l | sed -r 's/0+$//')" | |
echo "労働時間 = ${work_time}H" | |
echo "昼休憩 = ${STANDARD_BREAK_TIME_IN_MINUTES}min" | |
echo "途中休憩 = ${break_time_in_minutes}min" | |
exit ${EXIT_STATUS_SUCCESS} | |
} | |
function print_usage | |
{ | |
echo "${USAGE}" | |
} | |
if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then | |
main "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment