다가오는 지불 날짜까지 남은 일수를 표시해야 합니다(항상 매월 10일이라고 가정).
Bash에서 이 작업을 어떻게 수행합니까?
답변1
이제 날짜 형식 지정 기능은 있지만 bash
날짜 구문 분석이나 계산 기능은 없으므로 또는 같은 다른 셸이나 ksh93
또는 같은 zsh
적절한 프로그래밍 언어를 사용해야 할 수도 있습니다 .perl
python
의 경우 ksh93
문서화가 거의 되어 있지 않기 때문에 지원되는 날짜 형식을 찾는 것이 어려운 부분입니다(항상 확인할 수 있음).테스트 데이터예를 들어보세요).
예를 들어, crontab과 유사한 시간 사양을 지원하고 사양과 일치하는 다음 시간을 제공하므로 다음을 수행할 수 있습니다.
now=$(printf '%(%s)T')
next_10th=$(printf '%(%s)T' '* * 10 * *')
echo "Pay day is in $(((next_10th - now) / 86400)) days"
이제 표준 유틸리티가 있으므로 구현하기가 그리 어렵지 않습니다.
eval "$(date '+day=%d month=%m year=%Y')"
day=${day#0} month=${month#0}
if [ "$day" -le 10 ]; then
delta=$((10 - day))
else
case $month in
[13578]|10|12) D=31;;
2) D=$((28 + (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))));;
*) D=30;;
esac
delta=$((D - day + 10))
fi
echo "Pay day is in $delta days"
답변2
dom = 해당 월의 일
dom=6 ; \
days=$[ ${dom}-$(date +%-d) ] ; \
[ ${days} -lt 0 ] && days=$[ ${days} + $(date +%d -d "$(date +%Y%m01 -d 'next month') yesterday") ] ; \
echo ${days} days
30 days
답변3
echo $(expr '(' $(date -d 2017/03/10 +%s) - $(date +%s) + 86399 ')' / 86400) "days for my payment"
3 days for my payment
답변4
$td
선택한 예상 급여일에서 현재 날짜(오늘)를 뺍니다.
급여일이 현재 날짜보다 크면 결과는 긍정적이고 정확합니다.
예를 들어 td=8 및 pd=15:
$ td=8; pd=15
$ echo "The next PayDay will be in $((pd-td)) days"
7
결과가 음수이면 해당 월의 일수만 더합니다.
이를 수행하는 스크립트는 다음과 같습니다.
#!/bin/bash
pd=${1:-10} # Pay day selected
td=$( date -u +'%-d' ) # Today day of the month.
# To calculate the number of days in the present month.
MonthDays=$( date +'%-d' -ud "$(date +"%Y-%m-01T00:00:00UTC") next month last day" )
# Maybe a simpler alternative for current month last day:
# echo $(cal) | awk '{print $NF}' # $(cal) is unquoted on purpose.
# Make the next PayDay fit within the available days in the month.
# If the selected PayDay given to the script is 31 and the month
# only has 30 days, the next PayDay should be 30,
# not an un-existent and impossible 31.
pd=$(( (pd>MonthDays)?MonthDays:pd ))
res=$(( pd-td ))
# If the value of res is negative, just add the number of days in present month.
echo "Pay Day is in $(( res+=(res<0)?MonthDays:0 )) days"
고유 date
명령은 이번 달에만 사용해야 하므로 월/연도 경계를 넘지 않습니다. 이렇게 하면 거의 모든 문제를 피할 수 있습니다. 유일한 가정은 이번 달이 day 에 시작된다는 것입니다 01
. 또한 계산은 UTC+0으로 수행되므로 DST(일광 절약 시간) 또는 로컬 변경으로 인해 발생할 수 있는 문제를 방지할 수 있습니다.
선택한 급여일(예: 31)이 해당 월의 가능한 일수(예: 2월의 경우 28일)보다 큰 경우 프로그램은 해당 28일이 존재하지 않는 날짜(2월)가 아닌 급여일로 간주합니다. 31.
스크립트를 호출합니다(오늘이 9일인 경우).
$ ./script 7
Pay Day is in 29 days
$ ./script 16
Pay Day is in 7 days
$ ./script 31
Pay Day is in 19 days
하지만 오늘이 2월 28일이라면:
$ ./script 8
Pay Day is in 8 days
$ ./script 28
Pay Day is in 0 days
$ ./script 31
Pay Day is in 0 days