UNIX(non-posix)提供された日付に基づいて年中何日ですか?

UNIX(non-posix)提供された日付に基づいて年中何日ですか?

私は、UNIXプラットフォームの既存の日付から年ごとの日付(ユリウス歴の日付ではない)を取得する既存のソリューションを探していました。

存在すると確信していますが、まだ見つからず、うるう年などを計算するときに正確な結果を実行する数学は不明です。

答え1

あなたのラベルにそのように記載されているsolarisので、あなたが使用しているプラ​​ットフォームがまさにこれであると仮定します。

Solaris 11の標準インストールがある場合は、次のものをインストールした可能性がgdateあります。

私のインストールでは:

lrwxrwxrwx   1 root     root          15 Aug  3 13:21 /usr/bin/gdate -> ../gnu/bin/date*

したがって、GNUdateフラグを使用できます-d

例えば

% gdate +%j
222

% gdate -d "1970/06/23" +%j         
174

答え2

Pythonがインストールされている場合:

python -c 'import datetime; d=datetime.date(2016, 8, 9); print(d.timetuple().tm_yday)'

または環境変数に日付がある場合:

DATE=2016-08-09
python -c 'import datetime; d=datetime.strptime("'"$DATE"'", "%Y-%m-%d"); print(d.timetuple().tm_yday)'

(他の形式を解析するには調整する必要があります%Y-%m-%d)。

両方とも出力として提供されます222

答え3

Solaris 11(および/bin/shベース/bin/kshksh93

$ /bin/ksh -c 'printf "%(%-j)T\n" 2016-01-01 2016-08-09'
1
222

Solaris 10以前の場合は、いつでも次のものを使用できますperl

$ perl -MPOSIX -le '($y,$m,$d)=@ARGV;
                    print strftime "%j", 0,0,0, $d,$m-1,$y-1900
                   ' 2016 8 9
222

POSIXly(したがって、UNIXおよびUNIX準拠はPOSIX準拠を意味します)これらのPOSIX機能を使用できますsh(Solarisでは、POSIX / shUNIX/usr/xpg*/bin/shhttps://raw.githubusercontent.com/stephane-chazelas/misc-scripts/master/wide_strftime.sh:

$ timegm 2016 08 09 && wide_strftime '' "$REPLY" && echo "$T_j"
222

perlソリューションと同様に、0パディング(1は001)であり、パディングの削除はサポートされてい%-jません(最新バージョンではサポートされていますが、perlSolaris 10の非常に古い5.8.4バージョンではサポートされていません)。この機能を調整してパディングを削除するあります。)

ユリウス暦の日付自体は次の場所にあります$T_J

$ echo "$T_J"
2457609

答え4

答えてくれた皆さんに感謝します。しかし、これを達成するには、Solaris 10で数学を実装する必要があるようです。

私はこの問題を別の方法で解決することにしました。それはbash&bcを使って年中ユリウス暦の日付を計算することです。式は説明しますここ。元の機能を見つけることができますここ

以下の変更された関数は変換を実行してから2つの日付を比較できます。

function conv_date_to_julian()
{
  local cdate="$(date +%d:%m:%Y)"

  local day="${1:=$(echo ${cdate} | cut -d: -f1)}"
  local month="${2:=$(echo ${cdate} | cut -d: -f2)}"
  local year="${3:=$(echo ${cdate} | cut -d: -f3)}"
  local jdoy

  if [ ${month} -le 2 ]; then
    year=$(( ${year} - 1))
    month=$(( ${month} + 12))
  fi

  jdoy=$(echo "2 - ${year} / 100 + ${year} / 400" | bc)
  jdoy=$(echo "(${jdoy} + 365.25 * (${year} + 4716))/1" | bc) 
  jdoy=$(echo "(${jdoy} + 30.6001 * (${month} + 1))/1" | bc)

  echo $(echo "(${jdoy} + ${day} - 1524.5)" | bc)
}

使用例:

[ $(expr $(conv_date_to_julian 31 12 2017) - $(conv_date_to_julian)) -gt 30 ] && echo true

関連情報