创建功能以执行显示时间算术



尝试创建一个函数以获取一个数小时(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 / 60hr1 = hr1 + min1 / 60min1 / 60优先评估。壳算术仅是整数

min1 %= 60min1 = min1 % 60min1 / 60

的Modulo提醒
#!/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()函数(更新hr1min1中的值可能与以下几个相似:

## 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"

(注意:使用算术运算符进行比较时,例如((...)),将任何非智能值评估为 0em>输入,在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

最新更新