GNU Date는 현재 날짜에서 시간을 빼면 직관적으로 작동합니다.
date '+%F %R'; date '+%F %R' --date='- 1 hour'
2021-04-19 15:35
2021-04-19 14:35
그러나 날짜를 피연산자로 사용하면 결과가 예상치 못한 결과가 됩니다.
$ date '+%F %R' --date='2000/1/2 03:04:05 - 1 hour'
2000-01-02 06:04
$ date '+%F %R' --date='2000/1/2 03:04:05 + 1 hour ago'
2000-01-02 02:04
date
이 표현을 어떻게 해석해야 할까요 $date - 1 hour
?
답변1
간단히 말해서, --date
시간대를 지정하지 않으면 제공한 날짜는 현지 시간이 되며 비슷한 날짜는 +/- NNN
시간대로 처리됩니다. 그 이후에는 hour
단지 상대 수식어로 취급 되더라도 마찬가지입니다 . 따라서 - 1 hour
주어진 시간에서 1시간을 빼는 대신 UTC-01 시간대로 시간을 지정합니다.다음에 추가한 시간이면 충분합니다.
나는 그것이 당신이 시도하고 있는 것에 효과가 있을 것이라고 생각합니다. 오프셋 앞에 시간대를 명시적으로 제공하거나 오프셋을 넣어야 합니다.첫 번째따라서 시간대와 혼동할 수 없습니다.
여기서는 중앙 유럽 서머타임 시간대(CEST)와 오늘 날짜를 사용하고 %Z
출력에 추가하여 시간대를 표시합니다. ( %z
출력 숫자 시간대 또는 여기를 사용할 수도 있습니다 +0200
.)
$ date +'%F %T %Z' -d '2021-04-19 12:00:00 CEST + 5 hours'
2021-04-19 17:00:00 CEST
$ date +'%F %T %Z' -d '+ 5 hours 2021-04-19 12:00:00'
2021-04-19 17:00:00 CEST
물론, 문제의 1월 날짜에는 CEST와 같은 여름 시간대가 유효하지 않습니다. 그러나 두 가지를 다시 정렬하는 것은 여전히 작동하며 제공하는 시간은 해당 시간의 현지 시간과 같습니다.
$ date +'%F %T %Z' -d '+ 5 hours 2021-01-01 12:00:00'
2021-01-01 17:00:00 CET
( 2021-10-31 02:30:00
CET에도 그 시간이 있었음에도 불구하고 CET를 받았기 때문에...)
(바라보다구 버전다양한 입력을 해석하는 방법에 대한 추가 예는 이 답변을 참조하세요. )
~에 따르면다른 질문에 대한 @muru의 답변--debug
, 이 옵션을 사용하여 프로그램이 실제로 수행한 작업을 알려주도록 할 수도 있습니다 . 두 번째와 세 번째 줄을 참고하세요.
$ date --debug +'%F %T %Z' -d '2021-04-19 12:00:00 - 1시간' 날짜: 파싱된 날짜 부분: (YMD) 2021-04-19 날짜:구문 분석 시간 부분: 12:00:00 TZ=-01:00 날짜:관련 부분 구문 분석: +1시간 날짜: 입력 시간대: -01:00(구문 분석된 날짜/시간 문자열에서 설정) 날짜: 지정된 시간을 시작 값으로 사용: '12:00:00' 날짜: 시작 날짜/시간: '(YMD) 2021-04-19 12:00:00 TZ=-01:00' 날짜: '(YMD) 2021-04-19 12:00:00 TZ=-01:00' = 1618837200 epoch 초 날짜: 조정된 시간(+1시간, +0분, +0초, +0나노초), 날짜: 새 시간 = 1618840800 epoch 초 날짜: 출력 시간대: +01:00 (TZ="Europe/Berlin" 환경 값에서 설정) 날짜: 최종: 1618840800.000000000(에포크 초) 날짜: 최종: (YMD) 2021-04-19 14:00:00 (UTC0) 날짜: 최종: (YMD) 2021-04-19 16:00:00 (출력 시간대 TZ=+01:00) 2021-04-19 16:00:00 중앙 유럽 서머타임
매뉴얼 페이지에는 다음과 같이 나와 있습니다.
날짜 문자열 형식은 여기에 쉽게 문서화할 수 있는 것보다 더 복잡합니다 [...]
이것이 적절해 보입니다. 보다 포괄적인 문서는 정보 페이지나 온라인에 있습니다.https://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html
답변2
-디
예, -d 값이 단순하면 그 효과를 이해하기 쉽습니다.
예, -d '- 1 hour'
시간을 1시간 뒤로 이동합니다.
$ date ; date -d '- 1 hour'
Mon 19 Apr 2021 07:58:52 AM EDT
Mon 19 Apr 2021 06:58:52 AM EDT
시간대
결과 문자열은 date
"특정 시점"을 지정합니다.
기본적으로 "시점"은 현지 시간으로 기록됩니다. 그러나 UTC0으로 작성할 수도 있습니다.
$ date ; date -u
Mon 19 Apr 2021 12:43:04 PM WAT
Mon 19 Apr 2021 11:43:04 AM UTC
귀하의 현지 시간이 WAT - 서아프리카 표준시(WAT)라고 가정합니다.
물론 다른 시간대에서도 동일한 "시점"이 발생할 수 있습니다.
$ TZ=Asia/Kolkata date -d "Mon 19 Apr 2021 12:43:04 PM WAT"
Mon 19 Apr 2021 05:13:04 PM IST
이 값에 포함된 내용은 -d
위에 인쇄된 날짜입니다.
이는 시간대가 포함된 경우에만 "특정 시점"이 완료됨을 의미합니다.
그렇기 때문에 날짜를 추가 %z
하거나 추가 하여 인쇄하는 것이 좋습니다 . %Z
이런 의미에서 형식이 %F %R
불완전하므로 를 사용하는 것이 좋습니다 +'%F %R %z'
.
날짜 문자열
날짜를 사용할 때는 2000/1/2 03:04:05
시간대를 지정하지 않습니다.
이것이 바로 명령이 date
다음으로 - 1
시간대를 나타내는 이유입니다.
$ date -u -d '2000/1/2 03:04:05'; date -u -d '2000/1/2 03:04:05 - 1'
Sun 02 Jan 2000 03:04:05 AM WAT
Sun 02 Jan 2000 05:04:05 AM WAT
현지 시간이 WAT(DST로 인해 변경되지 않고 일광 절약 시간이 적용되지 않음)라고 가정합니다. %z
Nor 를 사용하지 않으시기 때문에 말씀드릴 수 없습니다 %Z
. 시간대를 변경하면 -d
값이 +1
(WAT) 에서 -1
2시간 차이로 변경됩니다.
또한 hour
그 후에 당신은 한 시간이 더 걸렸다고 썼습니다.
$ date -d '2000/1/2 03:04:05'; date -d '2000/1/2 03:04:05 - 1 hour'
Sun 02 Jan 2000 03:04:05 AM WAT
Sun 02 Jan 2000 06:04:05 AM WAT
결과를 확인하세요.
마지막으로 +1:
$ date -d '2000/1/2 03:04:05 - 1 hour'; date -d '2000/1/2 03:04:05 + 1 hour ago'
Sun 02 Jan 2000 06:04:05 AM WAT
Sun 02 Jan 2000 02:04:05 AM WAT
시간 값은 변경 되지 않지만 +1
(WAT에 있거나 이미 +1이기 때문에) hour ago
시간은 변경 됩니다.1한 시간 전(3시~2시)으로 돌아갑니다.
해결책
시간대를 -d
시간 값에 넣습니다.
또는 관련 부분을 먼저 배치하세요.- 1 hour
$ date -d '2000/1/2 03:04:05 +0100 - 1 hour'
Sun 02 Jan 2000 02:04:05 AM WAT
$ date -d '-1 hour 2000/1/2 03:04:05'
Sun 02 Jan 2000 02:04:05 AM WAT
답변3
다른 많은 날짜 처리 도구는 구문 분석 및 날짜 산술을 별도의 단계로 수행합니다. Perl을 예로 들어보겠습니다.
perl -sE '
use Time::Piece;
use Time::Seconds;
$t = Time::Piece->strptime($timestamp, $format);
say $t->cdate;
$s = $t + ONE_HOUR;
say $s->cdate;
$s = $t - ONE_HOUR;
say $s->cdate;
' -- -timestamp='2000/1/2 03:04:05' -format='%Y/%m/%d %T'
Sun Jan 2 03:04:05 2000
Sun Jan 2 04:04:05 2000
Sun Jan 2 02:04:05 2000