日付を減算するUNIXのツール


22

Solaris UNIXには日付を減算するツールがありますか(GNUツールはありません)?Linuxでは、gawkある日付を別の日付から差し引くことができることを知っています。ただし、Solarisでは、日付の計算を実行できない最大値nawk(改善awk)があります。また、perlは使用できません。

のような日付計算を行う方法はあります20100909 - 20001010か?

更新:bc日付の計算を実行できますか?


1
GNU日付がいつ利用可能かについては、日付の違いをすばやく計算するも参照してください。
ジル 'SO-悪であるのをやめる'

回答:


10

ここに書いたawkスクリプトは、POSIX awkで動作するはずです。Solarisバージョンを試す必要があります。SolarisにもAwkの2つのバージョンがあることを思い出してください。1つは/ binに、もう1つは/ usr / xpg4 / bin / awkにあります(nawkであると思います)。

BEGIN {
    daysofmonth["01"] = 0; daysofmonth["02"] = 31; daysofmonth["03"] = 59;
    daysofmonth["04"] = 90; daysofmonth["05"] = 120; daysofmonth["06"] = 151;
    daysofmonth["07"] = 181; daysofmonth["08"] = 212; daysofmonth["09"] = 243;
    daysofmonth["10"] = 273; daysofmonth["11"] = 304; daysofmonth["12"] = 334;
    fullday = 86400;
}
/[12][09][0-9][0-9][01][0-9][0123][0-9]/ {
    year = substr($0, 1, 4); month = substr($0, 5, 2); day = substr($0, 7, 2);
    date = ((year - 1970) * 365.25) + daysofmonth[month] + day - 1;
    if ((year % 4) == 0 && month > 2) { date = date + 1; }
    print date * fullday - (25200);
}
{}

YYYYmmdd日付文字列を渡すと、エポックからの秒数に変換されます(日の境界にいるために少しのギブがあります)。その後、2つを差し引くことができます。

today=`echo 20110210 | awk -f convdate.awk`
then=`echo 20001231 | awk -f convdate.awk`
sincethen=`expr $today - $then`

Oracleでロジックを確認しました。一部の日付では問題ありませんが、浮動小数点数を生成します。整数に切り捨てなければならないのではないでしょうか?
-jyz

小数は秒の小数部であり、必ずしも必要ではありません。
アルケージュ

エポックの有効期限は20380119です。年のユリウス日を使用しないのはなぜですか。だまされやすい人... unix.stackexchange.com/questions/302266/...
jas-

13

残念ながら、POSIXコマンドラインユーティリティはいずれも日付の算術演算を提供しません。date -dそしてdate +%s、あなたがそれらを持っているなら行く方法ですが、それらはGNU拡張です。

touch日付が少なくとも過去n日間であることを確認するために、その種の機能で不器用なハックがあります

touch -t 201009090000 stamp
if [ -n "$(find stamp -mtime +42)" ]; then ...

(DSTが間隔内に開始または停止し、スクリプトが午前1時より前に実行される場合、このコードは1つずつオフになる可能性があることに注意してください。)

何人かの人々が、BourneまたはPOSIXシェルで日付操作ライブラリを実装することになりました。comp.unix.shell FAQにはいくつかの例とリンクがあります。

GNUツールをインストールするのが最も簡単な方法かもしれません。


11

datePOSIXの一部であるコマンドを使用してみてください。更新:残念ながら、-dはPOSIX日付の一部ではなく、Solarisにも存在しない可能性があります。したがって、これはおそらくOPの質問に答えません。

d1=`date -d 20100909 +%s`
d2=`date -d 20001010 +%s`

d1d2UNIXエポック秒にその対応整数です。したがって、2つの違いを得るには、($((d1-d2))bashで)減算し、必要な単位に変換します。日が最も簡単です:

echo "$(((d1-d2)/86400)) days"

bashがない場合、変換の方法は異なる可能性があります。最も移植性の高い方法は、使用することですexprexprのposix manページ)。


ええこれはSolarisのだから、私の質問に答える...しかし:) ideiaと投稿をお願い致していません
JYZ

8

記録のために、dateutilsは、日付計算をカバーする一連のポータブルツールを提供する試みです。あなたの例は

ddiff -i '%Y%m%d' 20001010 20100909
=>
  3621

-i入力フォーマットを指定します。


2
このパッケージは素晴らしく、Ubuntuユニバースライブラリに存在します(少なくともTrusty向け)。別のシステムでは、ゼロから簡単にコンパイルできました。強くお勧めします。どうもありがとうございました!
ロバートミュール14年

RHエコシステム用にFedoraおよびEPELにもパッケージ化されています。
mattdm


3

SolarisのWRT GNU日付:

私はこれをもう一度言います:

多くのSolaris SysAdminは、新しいホストを構成するときにSolarisシステムを「GNU互換」にするSun(現在のOracle)の公式パッケージを意図的にインストールしないことに誇りを持っています。なぜ私を打つ。

GNU Dateは優れており、どのSolarisホストIMHOでもデフォルトで利用可能になっているはずです。

Solaris 10の場合

Solaris Companion CDからパッケージSFWcoreuをインストールします。インストール後、GNUの日付が見つかります/opt/sfw/bin/date

Solaris 11の場合

標準インストールの一部であると思われるので、既にお持ちかもしれません。ただしgdate、Sunバージョンの日付と区別するために呼び出されます。

インストールされていない場合、これを実行します。

pkg install // solaris / file / gnu-coreutils

ヒントをありがとう。使い方の例を教えてもらえますか?したがって、システム管理者にインストールを依頼することができます
...-jyz

Solarisの11で、それは両方としてインストールされます/usr/bin/gdate/usr/gnu/bin/date、あなたが名前または$ PATHの設定のいずれかによって、それを使用するかを選択できるようにします。
アランク

2

Pythonがある場合:

from time import *
date1 = strptime("20100909","%Y%m%d")
date2 = strptime("20001010","%Y%m%d")
diff = mktime(date1) - mktime(date2)
print repr(d/86400) + " days"

質問に「gawk」というタグを付けましたが、「GNUツールはありません」と言います。Gawkには日付演算があります。


しなかった。誰かが私の投稿を編集し、「gawk」というタグを付けました...
jyz

2

python:

 from datetime import datetime as dt
 a = dt(2010, 9, 9)
 b = dt(2000, 10, 10)
 print (a - b).days

1

1. date1およびdate2を年の%j日(001..366)形式で定義します

user@linux:~$ date1=`date -d 20100909 +%j` 
user@linux:~$ date2=`date -d 20001010 +%j`

2.差を計算します expr

user@linux:~$ datediff=`expr $date2 - $date1`

3.だから、答えは32日です

user@linux:~$ echo $datediff days
32 days
user@linux:~$ 

...またはワンライナーソリューション

user@linux:~$ echo $(( $(date -d 20001010 +%j) - $(date -d 20100909 +%j) )) days
32 days
user@linux:~$ 

または

user@linux:~$ expr $(date -d 20001010 +%j) - $(date -d 20100909 +%j)
32
user@linux:~$

または

user@linux:~$ expr `date -d 20001010 +%j` - `date -d 20100909 +%j`
32
user@linux:~$ 

0

macOSの日付BSDの場合:

echo "Quelle est la date de début ?"
read DATE_DE_DEBUT
echo "Quelle est la date de fin ?"
read DATE_DE_FIN
ANNEE=$(($(echo $DATE_DE_FIN | awk -F "/" '{print $3}')-$(echo $DATE_DE_DEBUT  | awk -F "/" '{print $3}')))

echo " "

if [[ $ANNEE > 0 ]]; then

for((annee=$ANNEE-1 ; $ANNEE ; annee++))

  do
  #echo $annee  
  for((mois=0 ; 13 - $mois ; mois++))
      do
  #   echo année:$annee mois:$mois
          for((jour=0 ; 32 - $jour ; jour++))
              do
 #             echo année:$annee mois:$mois jour:$jour
           TEST=$(date -Rjf"%d/%m/%Y" -v +"$annee"y -v +"$mois"m -v +"$jour"d $DATE_DE_DEBUT +"%d/%m/%Y")
           if [[ $TEST = $DATE_DE_FIN ]]; then
                  echo "Différence entre le $DATE_DE_DEBUT et le $DATE_DE_FIN";
                  echo "est de :";
                  echo "$annee année(s) $mois mois $jour jour(s)";
             exit 0;
            fi


          done 
  done
  done

 else 
 annee=0
 for((mois=0 ; 13 - $mois ; mois++))
      do
#      echo année:$annee mois:$mois
          for((jour=0 ; 32 - $jour ; jour++))
              do
              #echo année:$annee mois:$mois jour:$jour
              TEST=$(date -Rjf"%d/%m/%Y" -v +"$annee"y -v +"$mois"m -v +"$jour"d $DATE_DE_DEBUT +"%d/%m/%Y")
              if [[ $TEST = $DATE_DE_FIN ]]; then 
                      echo "Différence entre le $DATE_DE_DEBUT et le $DATE_DE_FIN";
                     echo "est de :";
                     echo "$annee année(s) $mois mois $jour jour(s)";
              exit 0;
              fi
              done
      done

fi

0

awk Velorライブラリを使用して、差を秒単位で返すことができます。

$ velour -n 'print t_utc(2010, 9, 9) - t_utc(2000, 10, 10)'
312854400

または日:

$ velour -n 'print t_secday(t_utc(2010, 9, 9) - t_utc(2000, 10, 10))'
3621
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.