사용자 정의 형식으로 날짜 빼기

사용자 정의 형식으로 날짜 빼기

일부 연결의 수명을 확인하려면 현재 날짜에서 일부 날짜를 빼야 합니다. 날짜 형식은 다음과 같습니다 YYMMDDHHMISS. 출력은 가장 오래된 연결, 1시간, 1주, 1개월보다 오래된 연결 수 등 확인하는 데 사용할 수 있는 거의 모든 것이 될 수 있습니다.

날짜 입력 예:211013134247

datecommand( ) 에서 이 형식의 날짜를 얻었지만 date '+%g%m%d%H%M%S'정확한 결과를 얻기 위해 이를 올바르게 빼는 방법을 모르겠습니다.


이렇게 해봤는데, 연결된 날짜의 숫자(예: 초) 중 하나가 현재 날짜보다 크자마자 문제가 발생합니다. 예: 연결 초는 53이고 현재 초는 47입니다.

$line = 연결 날짜
$date = 현재 날짜

  year=   $((${date:0:2} - ${line:0:2}))
  month=  $((${date:2:2} - ${line:2:2}))
  day=    $((${date:4:2} - ${line:4:2}))
  hour=   $((${date:6:2} - ${line:6:2}))
  minute= $((${date:8:2} - ${line:8:2}))
  second= $((${date:10:2} - ${line:10:2})) 

  age=$year$month$day$hour$minute$second

나도 이것을 시도했지만(스택 교환에서 일부 코드를 뻔뻔하게 훔쳤음) 출력이 잘못되었습니다. 나는 다음과 같은 것을 기대합니다: 0607********, 6년 7개월 등. 입력 날짜는 일반적으로 몇 년 간격으로 떨어져서는 안 되므로 연도 계산이 제외될 수 있습니다.

date="211013150325"
line="150325113419"
convert_date(){ printf `date '+%C'`'%s-%s-%s %s:%s:%s' ${1:0:2} ${1:2:2} ${1:4:2} ${1:6:2} ${1:8:2} ${1:10:2}; }
diff_dates(){
    TS1=$(date -d "$1" +%s)
    TS2=$(date -d "$2" +%s)
    TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S
    #+%Y.%m.%d.%H:%M:%S
}

date_converted=`convert_date $date`
echo $date_converted
line_converted=`convert_date $line`
echo $line_converted
diff_dates $date_converted $line_converted

root@SomeHost:~# date="211013150325"
root@SomeHost:~# line="150325113419"
root@SomeHost:~# convert_date(){ printf `date '+%C'`'%s-%s-%s %s:%s:%s' ${1:0:2} ${1:2:2} ${1:4:2} ${1:6:2} ${1:8:2} ${1:10:2}; }
root@SomeHost:~# diff_dates(){
>     TS1=$(date -d "$1" +%s)
>     TS2=$(date -d "$2" +%s)
>     TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S
>     #+%Y.%m.%d.%H:%M:%S
> }
root@SomeHost:~# 
root@SomeHost:~# date_converted=`convert_date $date`
root@SomeHost:~# echo $date_converted
2021-10-13 15:03:25
root@SomeHost:~# line_converted=`convert_date $line`
root@SomeHost:~# echo $line_converted
2015-03-25 11:34:19
root@SomeHost:~# diff_dates $date_converted $line_converted
701231085635

더 나은 전환을 얻기 위해 이를 제거 TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S하고 다른 것을 사용할 수 있습니까? 시간을 초 단위로 구할 수 있지만 echo $(($TS2-$TS1))1970년으로 시작하지 않는 날짜로 변환하는 방법을 모르겠습니다...


어쩌면 (거의 확실하게) 제가 이 일을 완전히 잘못하고 있는 것일 수도 있고 더 쉬운 방법이 있을 수도 있습니다.
이 내용을 정리하는 데 2시간 이상이 걸렸습니다. 이해가 되지 않는 부분이 있으면 지적해 주시면 수정하도록 노력하겠습니다.

답변1

존재하다 zsh:

zmodload zsh/datetime
timestamp=211013134247
strftime -rs t %y%m%d%H%M%S $timestamp
print $(( EPOCHSECONDS - t ))

이것은 %g당신이 찾고 있는 것이 아니라 iso 기념일이라는 점에 유의하십시오. 예를 들어 2021년 1월 1일입니다(여기에는 date비표준 GNU 구현이 있습니다 -d).

$ date -d 2021-01-01 +%gW%V-%A
20W53-Friday

2020년 ISO 53주차 금요일이며, 해당 주는 2021년보다 2020년에 일수가 더 많기 때문에 2021년에 한 주가 아닌 2020년에 한 주로 계산됩니다.

(ISO 주 번호) 에만 %g/를 사용 하고 싶습니다 . /는 현재 연도입니다.%G%V%y%Y

표준은 date날짜 구문 분석 및 출력을 위한 형식 재지정(시스템 시간 설정 대신)을 지원하지 않습니다. 그 중 일부는 서로 다르고 호환되지 않는 방식으로 확장 기능을 지원합니다. 이를 수행하는 구현 중 대부분은 strptime()( 위 zshstrftime내장 과 같은 -r) 스타일로 입력 형식을 지정하는 것을 지원하며, GNU는 date주목할만한 예외입니다.

  • ast-open datedate(컴파일 타임에 활성화된 경우 ksh93의 내장 명령이기도 함):

    $ date -p %y%m%d%H%M%S -d 211013134247 +%FT%T%z
    2021-10-13T13:42:47+0100
    $ date -p %y%m%d%H%M%S -d 211013134247 +%s
    1634128967
    
  • busybox date:

    $ date -D '%y%m%d%H%M%S' -d 211013134247 +%FT%T%z
    2021-10-13T13:42:47+0100
    $ date -D '%y%m%d%H%M%S' -d 211013134247 +%s
    1634128967
    
  • BSD date:

    $ date -jf %y%m%d%H%M%S 211013134247 +%FT%T%z
    2021-10-13T13:42:47+0100
    $ date -jf %y%m%d%H%M%S 211013134247 +%s
    1634128967
    

GNU의 경우 date타임스탬프를 지원되는 형식 중 하나로 변환해야 합니다.

표준 2021-10-13T13:42:47 형식일 수 있습니다.

$ timestamp=211013134247
$ date -d "20$(echo "$timestamp" | fold -w2 | paste -sd--T::)" +"%s"
1634128967

(연도가 2000년부터 2099년까지라고 가정합니다.)

또는 다음 ksh93을 포함하여 현재 일부 쉘에서 지원되는 -style을 사용하십시오.${param:offset:length}bash

$ date -d "20${t:0:2}-${t:2:2}-${t:4:2}T${t:6:2}:${t:8:2}:${t:10:2}" +%s
1634128967

답변2

시간을 초 단위로 알 수 있지만 echo $(($TS2-$TS1))날짜로 변환하는 방법을 모르겠습니다.

다음 명령을 사용하여 초를 시, 분, 초로 변환할 수 있습니다.

 date -d@$SECVAR -u +%H:%M:%S

변수에 SECVAR초가 포함된 경우

관련 정보