BASH:如何查找没有。两个日期之间的天数(仅考虑 "Network / Business Days")(即不包括周末 Saturday/Sunday)
BASH: How to find no. of days (considering only "Network / Business Days") between two dates (i.e. exclude weekends Saturday/Sunday)
RHEL7.5
BASH GNU bash,版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)
在MS Excel中,我可以使用网络天数来查找号码。两个日期之间的天数。想知道是否可以使用 bash 作为第一偏好(--或 Linux 上的任何其他 pre-installed 语言支持使用 one-liner 来解决这个问题——我的第二偏好)。我不确定 Linux 中是否存在计算此值的库或自定义 tool/utility。
- 要计算两个日期之间的工作日数,可以使用 NETWORKDAYS 函数。 NETWORKDAYS 会自动排除周末,它也可以选择排除自定义的假期列表。请注意,如果 NETWORKDAYS 是工作日,则计算中包括开始日期和结束日期。
我有一个 file.txt 包含 YYYY-mm-dd 格式的 2 个列字段,用于 Resolved 和 开始 日期(您现在可以忽略 header 行):
Resolved,StartOfWork
2020-01-16,2020-01-10
2020-01-13,2020-01-13
2020-01-20,2020-01-15
2020-01-20,2020-01-14
2020-01-14,2020-01-09
2020-01-09,2020-01-08
2020-01-16,2020-01-14
2020-01-09,2020-01-07
2020-01-14,2020-01-12
对于每一行,我想计算 否。网络,即这两个日期之间仅工作日(如果Resolved/StartOfWork日期在周末则无关紧要:Saturday/Sunday)。
- 数的计算天 不应包括 'weekend-days 即 Saturday/Sunday。
PS:就此 post 的目的而言,我的问题与此不同 post 要求:How to find the difference in days between two dates?
我会为此打电话给 Python 口译员。采用来自 Using Python to count the number of business days in a month? --
的公认答案
countBusinessDaysPy=$(cat <<'EOF'
import datetime, sys
businessdays = 0
startDate = datetime.date.fromisoformat(sys.argv[1])
endDate = datetime.date.fromisoformat(sys.argv[2])
if endDate < startDate:
(startDate, endDate) = (endDate, startDate)
while startDate <= endDate: # change from <= to < to not count both start and end days
if startDate.weekday() < 5:
businessdays += 1
startDate += datetime.timedelta(days=1)
print(businessdays)
EOF
)
countBusinessDays() { python3 -c "$countBusinessDaysPy" "$@"; }
...给你一个 shell 函数调用 Python 解释器来做你需要的数学(注意这是一个 inclusive 范围).此后:
$ countBusinessDays 2019-01-01 2020-01-01
262
$ countBusinessDays 2019-01-01 2019-01-07
5
在您的文件上调用此循环(请注意,在现实世界中,我会在 Python 中进行循环,而不是在 bash 中进行循环)可能看起来像:
{
read -r header; printf '%s\n' "$header,TotalDates"
while IFS=, read -r resolved startOfWork rest; do
printf '%s\n' "${resolved},${startOfWork}${rest:+,$rest},$(countBusinessDays "$startOfWork" "$resolved")"
done
} <yourInputFile
...作为输出发出:
Resolved,StartOfWork,TotalDates
2020-01-16,2020-01-10,5
2020-01-13,2020-01-13,1
2020-01-20,2020-01-15,4
2020-01-20,2020-01-14,5
2020-01-14,2020-01-09,4
2020-01-09,2020-01-08,2
2020-01-16,2020-01-14,3
2020-01-09,2020-01-07,3
2020-01-14,2020-01-12,2
这可能是重新发明轮子,但这里有一个bash解决方案(如果有兴趣的话)。
请注意,它需要 date
命令的 -d
选项。
while IFS="," read -r endday startday; do
if (( lineno++ == 0 )); then # handle header line
echo "Resolved,StartOfWork,TotalDates"
continue
fi
startsec=$(date -d "$startday" +%s)
startdayofweek=$(date -d "$startday" +%w) # 0 for Sun, ... 6 for Sat
endsec=$(date -d "$endday" +%s)
days=$(( (endsec - startsec) / 86400 + 1 )) # calendar days
weeks=$(( days / 7 )) # number of weeks
frac=$(( days % 7 )) # fraction mod 7
if (( startdayofweek == 0 )); then # case of starting on Sunday
if (( frac > 0 )); then
add=1 # additional number of holidays
else
add=0
fi
else
magic=$(( frac + (startdayofweek + 6) % 7 ))
# calculate number of holidays
# in the fraction period
if (( magic < 6 )); then
add=0
elif (( magic == 6 )); then
add=1
else
add=2
fi
fi
holidays=$(( weeks * 2 + add )) # total number of holidays
workdays=$(( days - holidays )) # subtract the holidays
echo "$endday,$startday,$workdays"
done < inputfile
RHEL7.5
BASH GNU bash,版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)
在MS Excel中,我可以使用网络天数来查找号码。两个日期之间的天数。想知道是否可以使用 bash 作为第一偏好(--或 Linux 上的任何其他 pre-installed 语言支持使用 one-liner 来解决这个问题——我的第二偏好)。我不确定 Linux 中是否存在计算此值的库或自定义 tool/utility。
- 要计算两个日期之间的工作日数,可以使用 NETWORKDAYS 函数。 NETWORKDAYS 会自动排除周末,它也可以选择排除自定义的假期列表。请注意,如果 NETWORKDAYS 是工作日,则计算中包括开始日期和结束日期。
我有一个 file.txt 包含 YYYY-mm-dd 格式的 2 个列字段,用于 Resolved 和 开始 日期(您现在可以忽略 header 行):
Resolved,StartOfWork
2020-01-16,2020-01-10
2020-01-13,2020-01-13
2020-01-20,2020-01-15
2020-01-20,2020-01-14
2020-01-14,2020-01-09
2020-01-09,2020-01-08
2020-01-16,2020-01-14
2020-01-09,2020-01-07
2020-01-14,2020-01-12
对于每一行,我想计算 否。网络,即这两个日期之间仅工作日(如果Resolved/StartOfWork日期在周末则无关紧要:Saturday/Sunday)。
- 数的计算天 不应包括 'weekend-days 即 Saturday/Sunday。
PS:就此 post 的目的而言,我的问题与此不同 post 要求:How to find the difference in days between two dates?
我会为此打电话给 Python 口译员。采用来自 Using Python to count the number of business days in a month? --
的公认答案countBusinessDaysPy=$(cat <<'EOF'
import datetime, sys
businessdays = 0
startDate = datetime.date.fromisoformat(sys.argv[1])
endDate = datetime.date.fromisoformat(sys.argv[2])
if endDate < startDate:
(startDate, endDate) = (endDate, startDate)
while startDate <= endDate: # change from <= to < to not count both start and end days
if startDate.weekday() < 5:
businessdays += 1
startDate += datetime.timedelta(days=1)
print(businessdays)
EOF
)
countBusinessDays() { python3 -c "$countBusinessDaysPy" "$@"; }
...给你一个 shell 函数调用 Python 解释器来做你需要的数学(注意这是一个 inclusive 范围).此后:
$ countBusinessDays 2019-01-01 2020-01-01
262
$ countBusinessDays 2019-01-01 2019-01-07
5
在您的文件上调用此循环(请注意,在现实世界中,我会在 Python 中进行循环,而不是在 bash 中进行循环)可能看起来像:
{
read -r header; printf '%s\n' "$header,TotalDates"
while IFS=, read -r resolved startOfWork rest; do
printf '%s\n' "${resolved},${startOfWork}${rest:+,$rest},$(countBusinessDays "$startOfWork" "$resolved")"
done
} <yourInputFile
...作为输出发出:
Resolved,StartOfWork,TotalDates
2020-01-16,2020-01-10,5
2020-01-13,2020-01-13,1
2020-01-20,2020-01-15,4
2020-01-20,2020-01-14,5
2020-01-14,2020-01-09,4
2020-01-09,2020-01-08,2
2020-01-16,2020-01-14,3
2020-01-09,2020-01-07,3
2020-01-14,2020-01-12,2
这可能是重新发明轮子,但这里有一个bash解决方案(如果有兴趣的话)。
请注意,它需要 date
命令的 -d
选项。
while IFS="," read -r endday startday; do
if (( lineno++ == 0 )); then # handle header line
echo "Resolved,StartOfWork,TotalDates"
continue
fi
startsec=$(date -d "$startday" +%s)
startdayofweek=$(date -d "$startday" +%w) # 0 for Sun, ... 6 for Sat
endsec=$(date -d "$endday" +%s)
days=$(( (endsec - startsec) / 86400 + 1 )) # calendar days
weeks=$(( days / 7 )) # number of weeks
frac=$(( days % 7 )) # fraction mod 7
if (( startdayofweek == 0 )); then # case of starting on Sunday
if (( frac > 0 )); then
add=1 # additional number of holidays
else
add=0
fi
else
magic=$(( frac + (startdayofweek + 6) % 7 ))
# calculate number of holidays
# in the fraction period
if (( magic < 6 )); then
add=0
elif (( magic == 6 )); then
add=1
else
add=2
fi
fi
holidays=$(( weeks * 2 + add )) # total number of holidays
workdays=$(( days - holidays )) # subtract the holidays
echo "$endday,$startday,$workdays"
done < inputfile