尝试创建一个函数以获取一个数小时(0-24(的数字和一个分钟(0-60(的数字,并在其中添加15分钟。问题是当我尝试将数字45及以上的数字放在60中时。
。创建的话,如果以下是我的输入的语句,如果分钟数超过60,则将从分钟变量中减去60,并添加1到小时变量。
。预期的结果是,如果超过60分钟到1小时并将剩余时间转换为几分钟。实际结果是,有时IF然后语句无法正确运行,并且同时可以进行,或者有时我会得到负数。
#!/bin/bash
read -p "Hours: " hr1
read -p "Minutes: " min1
min1=$((min1+15))
Time() {
echo $min1
if $min1 > 60
then
min1=$((min1-60))
if $min1 < 0
then $((min1*-1))
fi
hr1=$((hr1+1))
else
$min1 + 15
fi
}
Time
echo $min1
echo $hr1
您可以通过使用((
和))
界定的Shell Arithmetic表达式来大大简化Time()
函数。在这里,独立的算术表达式仅对bash壳有效,而在不确定的
(( hr1 += min1 / 60, min1 %= 60 ))
分成两个逗号,
分隔的表达式:
hr1 += min1 / 60
⇔ hr1 = hr1 + min1 / 60
将min1 / 60
优先评估。壳算术仅是整数
min1 %= 60
⇔ min1 = min1 % 60
min1 / 60
#!/usr/bin/env bash
read -r -p 'Hours: ' hr1
read -r -p 'Minutes: ' min1
# Bash stand-alone arithmetic expression add 15 to min1
(( min1+=15 ))
Time() {
echo "${min1}"
# Two Bash stand-alone arithmetic expressions separated by ,
# Add integer division of min1 by 60 to hr1
# Truncate min1 to the integer division reminder of itself by 60
(( hr1 += min1 / 60, min1 %= 60 ))
}
Time
echo "${min1}"
echo "${hr1}"
有很多很多方法可以将分钟添加到给定时间,然后获得由此产生的小时和分钟。系统的方法是将date
函数用作Oliver Gaida所示。手动转换适合学习目的,但是您需要确保您处理导致小时时间进入第二天的时间。
为了处理转换的各个方面,将总时间转换为秒是有用的。那时,您可以执行所有必要的测试,以确定第二天的总时间是否已滚动。
。由于您似乎只想捕获随之而来的时间的数小时和几分钟,并且不关心天数,因此您可以简单地测试每天秒的秒数果秒数超过秒秒,只需通过秒秒。。。
一个简短的功能getHM()
(您的Time()
函数(更新hr1
和min1
中的值可能与以下几个相似:
## function converting number of seconds to hours, minutes (discarding days)
getHM() {
test -z "$1" && { ## validate input given
printf "error: insufficient arguments getHM()n" >&2
return 1
}
local secs="$1" ## local variables seconds
local secsperday=$((3600 * 24)) ## seconds-per-day
local days=$((secs / secsperday)) ## days
(( days > 0 )) && { ## seconds exceed seconds-per-day
printf "error: time exceeds 24 hours, days discarded.n" >&2
secs=$((secs % secsperday)) ## reduce secs modulo by secsperday
}
hr1=$((secs / 3600)) ## update hr1 & min1 values
min1=$(((secs - hr1 * 3600) / 60))
}
如该功能中所述,它只是丢弃任何额外的日子,以返回所得小时(0-23
(和分钟(0-59
(。
将其添加到一个简短的示例中,您可以做:
#!/bin/bash
declare -i hr1=-1 min1=-1 addminutes=15 ## initialize variables
## function converting number of seconds to hours, minutes (discarding days)
getHM() {
test -z "$1" && { ## validate input given
printf "error: insufficient arguments getHM()n" >&2
return 1
}
local secs="$1" ## local variables seconds
local secsperday=$((3600 * 24)) ## seconds-per-day
local days=$((secs / secsperday)) ## days
(( days > 0 )) && { ## seconds exceed seconds-per-day
printf "error: time exceeds 24 hours, days discarded.n" >&2
secs=$((secs % secsperday)) ## reduce secs modulo by secsperday
}
hr1=$((secs / 3600)) ## update hr1 & min1 values
min1=$(((secs - hr1 * 3600) / 60))
}
## loop until valid input received
while ((hr1 < 0)) || ((hr1 > 23)) || ((min1 < 0)) || ((min1 > 59)); do
read -p "Hours: " hr1
read -p "Minutes: " min1
done
## convert all to seconds adding desired 15 minutes
secs=$((hr1 * 3600 + (min1 + addminutes) * 60))
getHM "$secs" ## call function to update hr1 & min1
printf "nHours : %dnMinutes : %dn" "$hr1" "$min1"
(注意:使用算术运算符进行比较时,例如((...))
,将任何非智能值评估为 0
em>输入,在read
完成后,您需要在while
循环中执行此操作 - 如果检测到非刻板值,则将变量重置为-1
(
示例使用/输出
无需小时调整:
$ bash gethm.sh
Hours: 23
Minutes: 44
Hours : 23
Minutes : 59
增加总时间在一天开始时精确着陆:
$ bash gethm.sh
Hours: 23
Minutes: 45
error: time exceeds 24 hours, days discarded.
Hours : 0
Minutes : 0
(注意:如果总时间导致了第二天的时间,则提供了错误消息。它仅是信息性的,您可以将其删除以适合您的需求(
示例显示了新的一天的1分钟:
$ bash gethm.sh
Hours: 23
Minutes: 46
error: time exceeds 24 hours, days discarded.
Hours : 0
Minutes : 1
看事物,让我知道您是否有其他问题
日期很容易。将日期转换为秒秒,添加900秒并将其转换回。
date --date="@$(echo $(($(date --date="22:53" +"%s")+900)))" +"%H:%M"
23:08