支払日数の計算

支払日数の計算

今後の支払い日までの残り日数を表示する必要があります(常に毎月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コマンドは今月のみ使用する必要があるため、月/年の境界を超えません。これにより、ほとんどすべての問題を回避できます。唯一の仮定は、今月が日に始まるということです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

関連情報