날짜를 빼는 UNIX의 도구


22

Solaris UNIX에 날짜를 빼기위한 도구가 있습니까 (GNU 도구를 사용할 수 없음)? 나는 리눅스에서 우리는 gawk날짜를 다른 날짜에서 뺄 수 있다는 것을 알고 있습니다. 그러나 Solaris에서는 날짜 계산을 수행 할 수없는 최대 값 nawk(개선 awk)이 있습니다. 또한 나는 펄을 사용할 수 없다.

날짜 계산을 수행하는 방법이 20100909 - 20001010있습니까?

업데이트 : bc날짜 계산을 수행 할 수 있습니까?


1
GNU 날짜를 사용할 수있는 경우 날짜 차이를 빠르게 계산을 참조하십시오 .
Gilles 'SO- 악마 그만해

답변:


10

내가 방금 작성한 awk 스크립트는 POSIX awk와 함께 작동해야합니다. 당신은 솔라리스 버전을 시도해야 할 것이다; Solaris에는 Awk의 두 가지 버전이 있습니다. 하나는 / bin과 다른 하나는 / usr / xpg4 / bin / awk입니다.

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 날짜 문자열을 전달하면 Epoch (일 경계에 약간의 영향을 미침) 이후 초 수로 변환됩니다. 그런 다음 둘을 뺄 수 있습니다.

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

나는 당신의 논리를 오라클과 확인했습니다. 일부 날짜에는 문제가 없지만 부동 소수점 숫자를 생성합니다. 정수로 자르는 것이 두렵습니까?
jyz

십진수는 1 초의 분수이며 반드시 필요한 것은 아닙니다.
Arcege

신기원은 20380119로 만료됩니다. 왜 율리우스의 날을 사용하지 않습니까? Dupe ... 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시 전에 실행되면이 코드가 하나씩 해제 될 수 있습니다.)

여러 사람들이 Bourne 또는 POSIX 셸에서 날짜 조작 라이브러리를 구현했습니다. comp.unix.shell FAQ 에 몇 가지 예제와 링크가 있습니다.

GNU 도구를 설치하는 것이 가장 힘들 수 있습니다.


11

datePOSIX의 일부인 명령을 사용하여 거의 모든 위치에 있습니다. 업데이트 : 불행히도 -d는 POSIX 날짜의 일부가 아니며 Solaris에는 없을 것 같습니다. 따라서 이것은 OP 질문에 대답하지 않을 것입니다.

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

이제 d1d2정수는 유닉스 시대 이후의 초에 그 대응이다. 따라서 둘 사이의 차이를 얻으려면 $((d1-d2))원하는 단위를 빼고 bash에서 빼십시오 . 일이 가장 쉽다 :

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

bash가 없으면 변환 방법이 다를 수 있습니다. 가장 휴대용 방법은 사용할 수 있습니다 expr( EXPR의 POSIX 맨 페이지 ).


그래, 이것은 솔라리스이기 때문에 내 질문에 대답하지 않지만 ...
이데아

8

기록을 위해 dateutils 는 날짜 산술을 다루는 휴대용 도구 세트를 제공하려는 시도입니다. 당신의 예는

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

-i입력 형식을 지정한다.


2
이 패키지는 훌륭하고 Ubuntu 유니버스 라이브러리에 있습니다 (적어도 Trusty 용). 다른 시스템에서는 처음부터 쉽게 컴파일 할 수 있습니다. 추천. 대단히 감사합니다!
Robert Muil

RH 생태계를 위해 Fedora 및 EPEL로 패키지되었습니다.
mattdm

4

Perl이 설치되었을 가능성이 높으며 CPAN 에서 모듈을 가져와 홈 디렉토리에 설치 한 후 프로그램에서 참조 하기에 충분합니다 . 이 경우 Date :: Calc 모듈에는 Delta_Days도움 이되는 서브 루틴이 있습니다.


3

Solaris에서 Wrt GNU 날짜 :

나는 이것을 다시 말한다 :

너무 많은 Solaris SysAdmins는 새로운 호스트를 구성 할 때 Solaris 시스템을 "GNU 호환"으로 만드는 Sun (현재 Oracle)의 공식 패키지를 의도적으로 설치하지 않는 것에 자부심을 가지고 있습니다. 왜 나에게 이겼다.

GNU Date는 훌륭하며 기본적으로 모든 IMHO 호스트에서 사용할 수 있어야합니다.

Solaris 10에서

Solaris Companion CD에서 SFWcoreu 패키지를 설치하십시오. 설치 후 GNU 날짜를 찾을 수 있습니다/opt/sfw/bin/date

Solaris 11에서

표준 설치의 일부라고 생각하므로 이미 가지고있을 수 있습니다. 그러나 gdateSun 버전의 날짜와 구별하기 위해 호출 됩니다.

설치되지 않은 경우이 작업을 수행하십시오.

pkg 설치 // solaris / file / gnu-coreutils

팁 고마워. 어떻게 사용하는지 예를 들어 주시겠습니까? sysadmin에 설치하도록 요청할 수 있습니다 ...
jyz

솔라리스 11, 그것은 모두로 설치됩니다 /usr/bin/gdate/usr/gnu/bin/date그래서 당신은 이름이나 $ PATH 설정에 의해 중 하나를 선택하여 사용할 수 있습니다.
alanc

2

파이썬이 있다면 :

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

파이썬 :

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

1

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

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.