web-dev-qa-db-ja.com

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

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

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

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

23
jyz

これは私が書いたばかりのawkスクリプトで、POSIX awkで動作するはずです。 Solarisバージョンを試す必要があります。 Solarisにも2つのバージョンのAwkがあることを思い出してください。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`
10
Arcege

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

touchを使った不格好なハックがあります。これは、日付が過去n日以上であることを確認するために機能します。

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

(DSTがインターバル内で開始または停止し、スクリプトが午前1時より前に実行された場合、このコードは1つずれる場合があることに注意してください。)

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

GNUツールをインストールすることで、痛みを最小限に抑えることができます。

POSIXの一部であるdateコマンドを使用してみます。 更新:残念ながら、-dはPOSIX日付の一部ではなく、Solarisにはないようです。したがって、これはOPの質問に回答しない可能性があります。

_d1=`date -d 20100909 +%s`
d2=`date -d 20001010 +%s`
_

ここで_d1_および_d2_は、UNIXエポック以降の秒数に対応する整数です。したがって、2つの間の差を取得するには、減算($((d1-d2)) in bash)して、必要な単位に変換します。日が最も簡単です:

_echo "$(((d1-d2)/86400)) days"
_

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

11
Steven D

記録として、 dateutils は、日付の計算をカバーするポータブルツールのセットを提供しようとする私の試みです。あなたの例は次のように要約されます

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

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

8
hroptatyr

Perlがインストールされる可能性が高く、 [〜#〜] cpan [〜#〜] からモジュールを取得して自宅にインストールするのは簡単ですディレクトリ、および プログラムでそれらを参照します 。この場合、 Date :: Calc モジュールにはDelta_Days役立つサブルーチン。

4
glenn jackman

Wrt GNU Solarisの日付:

私は再びこれを言います:

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

GNU Dateは優れており、デフォルトですべてのSolarisホストであるIMHOで利用できるはずです。

Solaris 10の場合

Solaris Companion CDからパッケージSFWcoreuをインストールします。インストール後、GNU date in /opt/sfw/bin/date

Solaris 11の場合

私はそれが標準インストールの一部であると信じているので、あなたはすでにそれを持っているかもしれません。ただし、Sunバージョンの日付と区別するためにgdateと呼ばれています。

インストールされていない場合は、次のようにします。

pkgインストール// solaris/file/gnu-coreutils
3
peterh

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」というタグを付けましたが、「no GNU tools」と言います。Gawkには日付計算機能があります。

python:

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

1。 %j日(001..366)形式でdate1とdate2を定義します

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:~$ 
1
Sabrina

Awk ベロアライブラリ を使用して、秒単位で差を返すことができます。

$ 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
0
Steven Penny

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
OlivierOR