날짜 차이를 빠르게 계산


84

종종 다음과 같은 빠른 날짜 계산을 원합니다.

  • 이 두 날짜의 차이점은 무엇입니까?
  • 이 다른 날짜 로부터 n 주 후의 날짜는 얼마입니까?

나는 보통 달력을 열고 일수를 세지 만, 이런 종류의 계산을 수행하는 데 사용할 수있는 프로그램 / 스크립트가 있어야한다고 생각합니다. 어떤 제안?


3
GNU 날짜를 사용할 수없는 경우 날짜를 빼려면 UNIX의 도구를 참조하십시오 .
Gilles

답변:


106

GNU 날짜 (1)를 사용하면 "날짜 후 n 주"는 쉽습니다.

$ date -d 'now + 3 weeks'
Tue Dec  6 23:58:04 EST 2011
$ date -d 'Aug 4 + 3 weeks'
Thu Aug 25 00:00:00 EST 2011
$ date -d 'Jan 1 1982 + 11 weeks'
Fri Mar 19 00:00:00 EST 1982

두 날짜의 차이를 계산하는 간단한 방법을 모르지만 쉘 함수를 사용하여 date (1) 주위에 작은 논리를 줄 수 있습니다.

datediff() {
    d1=$(date -d "$1" +%s)
    d2=$(date -d "$2" +%s)
    echo $(( (d1 - d2) / 86400 )) days
}
$ datediff '1 Nov' '1 Aug'
91 days

스왑 d1d2는 날짜 계산을 다른 방법을 원하거나받을 경우 애호가 약간은 문제가되지 확인하십시오. 또한, 구간에서 비 DST에서 DST 로의 전환이있는 경우 하루 중 하나의 시간은 23 시간입니다. 합계에 ½ 일을 추가하여 보상 할 수 있습니다.

echo $(( (((d1-d2) > 0 ? (d1-d2) : (d2-d1)) + 43200) / 86400 )) days

40

휴대용 도구 세트는 내 고유 한 dateutils를 사용해보십시오 . 두 가지 예는 하나의 라이너로 요약됩니다.

ddiff 2011-11-15 2012-04-11
=>
  148

또는 몇 주와 며칠 동안 :

ddiff 2011-11-15 2012-04-11 -f '%w %d'
=>
  21 1

dadd 2011-11-15 21w
=>
  2012-04-10

3
+1 툴 바위를 (비록 dateadd -i '%m%d%Y' 01012015 +1d? 작동하지 않는 것, 그냥 날짜 사양은 문자, 어떤 문자 ... 뭐가 잘못 어떤 생각으로 구분하는 경우 작동합니까 ... 무기한가 달려)
don_crissti

2
@don_crissti 파서는 숫자 전용 날짜와 기간을 구분하지 수, 그것은 현재 마스터 (d0008f98)에 고정 된 것
hroptatyr

dateutils에 대한 윈도우의 바이너리 배포가 있습니까?
mosh

@ mosh no, 그리고 시도 할 시설이 없습니다.
hroptatyr

파티에 늦었지만 Windows에서 사용해야하는 경우 dateutils는 cygwin에 있습니다.
gregb212

30

내가 지구를 걷는 일 수를 계산하는 파이썬 예제 :

$ python
>>> from datetime import date as D
>>> print (D.today() - D(1980, 6, 14)).days
11476

2
누군가가 인터랙티브 인터프리터를 입력하는 대신 단일 명령처럼 동작하기를 원하는 경우를 대비하여 : ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days" 12813 ychaouche@ychaouche-PC ~ $
ychaouche

1
이것은 나를 위해 작동합니다 python3 -c "날짜 가져 오기 날짜에서 d로; 인쇄 (d.today ()-d (2016, 1, 9))"일이 필요하지 않습니다
Kiran K Telukunta

13

나는 일반적으로 유닉스 utime 형식 (70 년대가 시작된 신기원 이후의 시간, UTC)으로 시간 / 날짜를 갖는 것을 선호합니다. 그렇게하면 항상 평범한 빼기 또는 초 추가로 귀결됩니다.

문제는 일반적으로 날짜 / 시간을이 형식으로 변환하는 것입니다.

쉘 환경 / 스크립트 date '+%s' 에서는 다음 과 같이 얻을 수 있습니다 1321358027. 현재 시간은 입니다.

2011-11-04 (나의 생일)과 비교 date '+%s' -d 2011-11-04하여 1320361200. 빼기 : 초를 expr 1321358027 - 1320361200제공합니다 . = 11 일 전입니다.996827expr 996827 / 86400

표준 라이브러리를 사용하여 utime (1320361200 형식)에서 날짜로 변환하는 것은 C, PHP 또는 perl과 같이 매우 간단합니다. GNU를 사용하면 "Epoch 이후 두 번째"형식을 나타 내기 date위해 -d인수 앞에 붙일 수 있습니다 @.


7
GNU 날짜를 사용 date -d @1234567890하면 신기원 이후의 초를 지정한 날짜 형식으로 변환합니다.
Gilles

1
@Gilles : 훌륭합니다. 맨 페이지에서 찾을 수 없습니다. 어디서 배웠어요?
MattBianco

1
@MattBianco의 경우 info date특히 Epoch 노드 이후초를 참조하십시오 .“@ 앞에 숫자를
붙이면

8

이것은 date -d "$death_date - $y years - $m months - $d days"생년월일을 얻기 위해 사용할 때 (계보를 위해) 나타났습니다 . 그 명령은 잘못되었습니다. 월의 길이는 같지 않으므로 (date + offset) - offset != date. 연도 / 월 / 일의 나이는 생년월일부터 앞으로의 측정입니다.

$ date --utc -d 'mar 28 1867 +72years +11months +2days'
Fri Mar  1 00:00:00 UTC 1940

$ date --utc -d 'mar 1 1940 -72years -11months -2days'
Sat Mar 30 00:00:00 UTC 1867
# (2 days later than our starting point)

날짜는 두 경우 모두 올바른 결과를 제공하지만 두 번째 경우에는 잘못된 질문을합니다. 일을 더하거나 빼기 전에 연중 11 개월 동안 +/- 11 표지에 중요합니다. 예를 들면 다음과 같습니다.

$ date --utc -d 'mar 31 1939  -1month'
Fri Mar  3 00:00:00 UTC 1939
$ date --utc -d 'mar 31 1940  -1month' # leap year
Sat Mar  2 00:00:00 UTC 1940
$ date --utc -d 'jan 31 1940  +1month' # leap year
Sat Mar  2 00:00:00 UTC 1940

빼기가 더하기의 역 연산이 되려면 연산 순서를 반대로해야합니다. 추가하면 년, THEN 개월, THEN 일이 추가됩니다. 빼기가 반대 순서를 사용하면 시작점으로 돌아갑니다. 요일 오프셋이 다른 길이의 월에있는 월 경계를 넘는 경우에는 그렇지 않습니다.

종료 날짜 및 연령부터 거꾸로 작업해야하는 경우을 여러 번 호출하여 수행 할 수 date있습니다. 먼저 일, 월, 년을 뺍니다. ( date윤년이 2 월 길이를 변경하기 때문에 연도 및 월을 단일 호출 로 결합하는 것이 안전하지 않다고 생각합니다 .)


7

그래픽 도구가 괜찮다면, qalculate단위 변환에 중점을 둔 계산기, GTK 및 KDE 인터페이스 IIRC가 함께 제공됩니다. 거기 당신은 말할 수 있습니다

days(1900-05-21, 1900-01-01)

날짜 사이의 일 수 (1900 년 이후 윤년이 아닌 140)를 얻으려면 물론 시간에도 동일하게 수행 할 수 있습니다.

17:12:45 − 08:45:12

8.4591667시간을 산출 하거나 출력을 시간 형식으로 설정하면 8:27:33.


3
qalculate 에는 CLI 있기 때문에 훌륭 합니다. qalc그런 다음 시도하십시오 help days.
Sparhawk

qcalc예 : qalc -t 'days(1900-05-21, 1900-01-01)'-> 140
sierrasdetandil

3

날짜 계산에 자주 SQL을 사용합니다. 예를 들어 MySQL , PostgreSQL 또는 SQLite :

bash-4.2$ mysql <<< "select datediff(current_date,'1980-06-14')"
datediff(current_date,'1980-06-14')
11477

bash-4.2$ psql <<< "select current_date-'1980-06-14'"
 ?column? 
----------
    11477
(1 row)

bash-4.2$ sqlite2 <<< "select julianday('now')-julianday('1980-06-14');"
11477.3524537035

다른 경우에는 JavaScript에 대해 기분이 좋았습니다. 예를 들어 SpiderMonkey , WebKit , Seed 또는 Node.js :

bash-4.2$ js -e 'print((new Date()-new Date(1980,5,14))/1000/60/60/24)'
11477.477526192131

bash-4.2$ jsc-1 -e 'print((new Date()-new Date(1980,5,14))/1000/60/60/24)'
11477.47757960648

bash-4.2$ seed -e '(new Date()-new Date(1980,5,14))/1000/60/60/24'
11477.4776318287

bash-4.2$ node -pe '(new Date()-new Date(1980,5,14))/1000/60/60/24'
11624.520061481482

(월을 JavaScript Date객체의 생성자 로 전달할 때주의하십시오 . 0으로 시작합니다.)


3

같은 연도의 두 날짜 간의 차이를 계산하는 또 다른 방법은 다음을 사용할 수 있습니다.

date_difference.sh
1  #!/bin/bash
2  DATEfirstnum=`date -d "2014/5/14" +"%j"`
3  DATElastnum=`date -d "12/31/14" +"%j"`
4  DAYSdif=$(($DATElastnum - $DATEfirstnum))
5  echo "$DAYSdif"
  • 1 행은 사용할 인터프리터를 쉘에 선언합니다.
  • 2 행은 out에서 out의 값을 dateDATEfirstnum 변수에 지정합니다. -d플래그는이 경우 5 월 14 일 2014 년 시간 형식 문자열을 표시하고 +"%j"알려줍니다 date년 (1-365)의 바로 일에 출력을 포맷 할 수 있습니다.
  • 3 행은 2 행과 동일하지만 문자열의 날짜 및 형식이 다릅니다 (2014 년 12 월 31 일).
  • 4 행 DAYSdif은 이틀 차이에 값 을 지정합니다 .
  • 5 행은 값을 표시합니다 DAYSdif.

이것은 GNU 버전의 date에서는 작동 하지만 PC-BSD / FreeBSD 버전 에서는 작동 하지 않습니다. coreutils포트 트리에서 설치 하고 /usr/local/bin/gdate대신 명령을 사용했습니다.


1
이 스크립트는 실행되지 않습니다. 마지막 줄에 오타가 있고 변수 할당 주위에 공백이 있으므로 bash는 두 개의 인수로 DATEfirst name이라는 프로그램을 실행하려고합니다. 이것을 시도하십시오 : DATEfirstnum=$(date -d "$1" +%s) DATElastnum=$(date -d "$2" +%s) 또한이 스크립트는 서로 다른 두 해의 차이를 계산할 수 없습니다. +%j연도 (001..366)를 나타내므로 ./date_difference.sh 12/31/2001 12/30/2014-1을 출력합니다. 다른 답변에서 알 수 있듯이 두 날짜를 1970-01-01 00:00:00 UTC 이후의 초로 변환해야합니다.
Six

$내부 산술 표현식이 필요하지 않습니다 $((DATElastnum - DATEfirstnum)). 작동합니다.
Ruslan

3

dannas 솔루션의 도움으로 다음 코드를 사용하여 한 줄로 수행 할 수 있습니다.

python -c "from datetime import date as d; print(d.today() - d(2016, 7, 26))"

(Python 2.x 및 Python 3 모두에서 작동합니다.)


1
댓글 대신 댓글을 편집 할 수 있습니다
Stephen Rauch

3

datebash는 날짜 차이를 표시 할 수 있습니다 (OS X 옵션 표시). 후자를 먼저 배치하십시오.

echo $((($(date -jf%D "04/03/16" +%s) - $(date -jf%D "03/02/16" +%s)) / 86400))
# 31

1

GNU 날짜와 결합 된 GNU 단위의 시간 계산도 있습니다.

$ gunits $(gdate +%s)sec-$(gdate +%s -d -1234day)sec 'yr;mo;d;hr;min;s'
        3 yr + 4 mo + 16 d + 12 hr + 37 min + 26.751072 s
$ gunits $(gdate +%s -d '2015-1-2 3:45:00')sec-$(gdate +%s -d '2013-5-6 7:43:21')sec 'yr;mo;d;hr;min;s'
        1 yr + 7 mo + 27 d + 13 hr + 49 min + 26.206759 s

(gunit는 Linux 단위이며, gdate는 날짜입니다)


1

github의 datediff.sh:gist

#!/bin/bash
#Simplest calculator two dates difference. By default in days

# Usage:
# ./datediff.sh first_date second_date [-(s|m|h|d) | --(seconds|minutes|hours|days)]

first_date=$(date -d "$1" "+%s")
second_date=$(date -d "$2" "+%s")

case "$3" in
"--seconds" | "-s") period=1;;
"--minutes" | "-m") period=60;;
"--hours" | "-h") period=$((60*60));;
"--days" | "-d" | "") period=$((60*60*24));;
esac

datediff=$(( ($first_date - $second_date)/($period) ))
echo $datediff

1

camh의 답변 이 대부분을 처리하지만 반올림, 시간대 등을 처리하도록 개선 할 수 있으며 추가 정밀도와 단위 선택 기능을 얻을 수 있습니다.

datediff() {
#convert dates to decimal seconds since 1970-01-01 00:00:00 UTC
date1seconds=$(date +%s.%N -d "$date1")
date2seconds=$(date +%s.%N -d "$date2")

#Calculate time difference in various time units
timeseconds=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)"))
timeminutes=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/60"))
  timehours=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/3600"))
   timedays=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/86400"))
  timeweeks=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/604800"))
}

-d알려줍니다 date우리가 변환하는 날짜와 시간을 공급하고있다. +%s.%N1970-01-01 00:00:00 UTC 이후 날짜-시간을 초로 변경합니다. bc두 숫자의 차이를 계산하고 나누는 요소가 다른 단위를 얻습니다. printf필요한 경우 소수점 이하 자릿수 앞에 0을 추가하고 ( bc반사하지 않음) 반올림을 가장 가깝게 bc만듭니다 ( 단지 잘라냅니다). 당신은 또한 사용할 수 있습니다 awk.

이제 펑키 테스트 케이스로 실행 해 봅시다.

date1='Tue Jul  9 10:18:04.031 PST 2020'
date2='Wed May  8 15:19:34.447 CDT 2019'
datediff "$date1" "$date2"

echo $timeseconds seconds
-36971909.584000000 seconds

echo $timeminutes minutes
-616198.493066667 minutes

echo $timehours hours
-10269.974884444 hours

echo $timedays days
-427.915620185 days

echo $timeweeks weeks
-61.130802884 weeks

한 달 또는 연도의 길이가 항상 동일하지는 않기 때문에 단일 "정확한"대답은 없지만 현재 365.24 일을 합리적인 근사치로 사용할 수 있습니다.


0

awk Velor 라이브러리를 사용할 수 있습니다 .

velour -n 'print t_secday(t_utc("2017-4-12") - t_utc("2017-4-5"))'

또는:

velour -n 'print t_secday(t_utc(ARGV[1]) - t_utc(ARGV[2]))' 2017-4-12 2017-4-5

결과:

7
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.