지불 일수 계산

지불 일수 계산

다가오는 지불 날짜까지 남은 일수를 표시해야 합니다(항상 매월 10일이라고 가정).

Bash에서 이 작업을 어떻게 수행합니까?

답변1

이제 날짜 형식 지정 기능은 있지만 bash날짜 구문 분석이나 계산 기능은 없으므로 또는 같은 다른 셸이나 ksh93또는 같은 zsh적절한 프로그래밍 언어를 사용해야 할 수도 있습니다 .perlpython

의 경우 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

관련 정보