일 이내의 시차를 계산합니다.

일 이내의 시차를 계산합니다.

시간을 에포크(Epoch)로 변환한 다음 그 차이를 초로 변환하여 두 시간의 차이를 계산하는 방법을 보여주는 많은 질문과 예제를 보았습니다. 하지만 시간의 차이를 계산하는 가장 좋은 방법은 무엇입니까? $ DAY 일, $HOUR, HOURS, $MIN MINUTES 및 $SEC 초?

내 목적에 맞게 날짜 형식인 date+"%m/%d/%y %T"(08/17/18 09:03:31)를 사용하고 있습니다.

첫 번째 데이트가 08/15/18 16:22:05이고 두 번째 데이트가 08/17/18 09:03:31이라고 가정합니다. "차이는 1일 16시간 41분 26초입니다."를 에코하여 차이를 계산하는 방법입니다.

그리고 동일한 스크립트를 사용하여 "차이는 0일입니다..."라고 보고하지 않고 시차가 1일 미만인지 어떻게 식별합니까?

편집: 아래에는 대부분 작동하는 스크립트가 있지만 올바른 형식을 유지하려면 수행해야 할 작업이 더 많습니다. 값이 0인지 아닌지에 따라 적절한 공백과 쉼표를 제외하고는 모든 것이 작동하는 것 같습니다.

"0"과 같은 값을 제거할 때 적절한 위치에 "and" 형식을 지정해야 한다는 아이디어입니다.

따라서 모든 값은 02:05:23:44 2일 5시간 23분 44초입니다.

시간 없음: 02:00:23:44 2일 23분 44초

초 없음: 02:05:23:00 2일 5시간 23초

얼마 전까지만 해도 꽤 가까웠는데, 좀 읽어보니 무너지네요. 내가 원하는 형식에 대한 도움이 필요합니까? 스크립트도 엉망입니다. 스크립트를 정리하는 데 도움이 필요합니다. 효율성을 높이는 방법을 알고 싶습니다.

#!/bin/bash
TIME1="08/17/2018 11:36:40"
TIME2="08/17/2018 12:37:41"
SEC1=`date +%s -d "${TIME1}"`
SEC2=`date +%s -d "${TIME2}"`
DIFF=`expr ${SEC2} - ${SEC1}`

CONVERTTIME() {
  ((d=${1}/86400))
  ((h=(${1}%86400)/3600))
  ((m=(${1}%3600)/60))
  ((s=${1}%60))

  #DAYS
  if [ $d -eq 1 ]; then
    DAYLABEL=day
  else
    DAYLABEL=days
  fi
  DAYCOMMA=", "
  if [[ $d -gt 0 || $h && $m && $s -eq 0 ]]; then
    DAYCOMMA=""
  fi
  DAYTEXT="$d $DAYLABEL$DAYCOMMA"
  if [ $d -eq 0 ]; then
    DAYTEXT=
  else
    if [ $h -eq 0 ]; then
      DAYTEXT="$d $DAYLABEL$DAYCOMMA"
    fi
  fi
  #HOURS
  if [ $h -eq 1 ]; then
    HOURLABEL=hour
  else
    HOURLABEL=hours
  fi
  HOURCOMMA=", "
  if [[ $h -gt 0 || $m && $s -eq 0 ]]; then
    HOURCOMMA=""
  fi
  HOURTEXT="$h $HOURLABEL$HOURCOMMA"
  if [ $h -eq 0 ]; then
    HOURTEXT=""
  else
    if [ $m -eq 0 ]; then
      HOURTEXT="$h $HOURLABEL$HOURCOMMA"
    fi
  fi
  #MINUTES
  if [ $m -eq 1 ]; then
    MINLABEL=minute
  else
    MINLABEL=minutes
  fi
  MINCOMMA=", "
  if [[ $m -gt 0 || $s -eq 0 ]]; then
    MINCOMMA=""
  fi  
  MINTEXT="$m $MINLABEL$MINCOMMA"
  if [ $m -eq 0 ]; then
    MINTEXT=""
  else
    if [ $s -eq 0 ]; then
      MINTEXT="$d $MINLABEL$MINCOMMA"
    fi
  fi
  #SECONDS
  if [ $s -eq 1 ]; then
    SECLABEL=second
  else
    SECLABEL=seconds
  fi
  SECTEXT="$s $SECLABEL"
  if [ $s -eq 0 ]; then
    SECTEXT=""
  fi

  ANDHOUR=
  ANDMIN=
  ANDSEC=
  if [[ $d && $h && $m && $s -gt 0 || $d && $h && $s -gt 0 || $d && $m && $s -gt 0 || $h && $m && $s -gt 0 || $d && $s -gt 0 || $h && $s -gt 0 || $m && $s -gt 0 ]]; then
    ANDSEC="and "
  else
    #days hours AND minutes
    #days AND minutes
    #hours AND minutes
    if [[ $d && $h && $m -gt 0 || $d && $m -gt 0 || $h && $m -gt 0 ]]; then
      ANDMIN="and "  
    else
      #days AND hours
      if [[ $d && $h -gt 0 ]]; then
        ANDHOUR="and "
      fi
    fi  
  fi
  echo -e "$DAYTEXT$ANDHOUR$HOURTEXT$ANDMIN$MINTEXT$ANDSEC$SECTEXT"
}
echo
echo "TIME DIFFERENCE: $(CONVERTTIME $DIFF)"
echo

답변1

일부 줄에서는(GNU 날짜를 가정):

$ diff=$(($(date -ud '08/17/18 09:03:31' +'%s') - $(date -ud '08/15/18 16:22:05' +'%s')))
$ days=$(($(date -ud @$diff +'%-j')-1)) 
$ date -ud @"$diff" +"$days"'-day(s) %H:%M:%S'
1-day(s) 16:41:26

최대 (약) 365일 동안 유효합니다.

스크립트로:

#!/bin/sh

tosec(){ secs=$(date -ud "$1" +'%s'); }

tosec "$1"; sec1=$secs 
tosec "$2"; sec2=$secs
diff=$((sec2-sec1))
eval "$(date -ud "@$diff" +'days=%-j time=%H:%M:%S')"
printf '%s\n' "$((days-1))-day(s) $time"

불러라:

$ ./script '08/15/18 16:22:05'   '08/17/18 09:03:31'

답변2

나는 당신의 대본을 연구한 결과 다음과 같은 결론을 내렸습니다.

#!/bin/bash
TIME1="08/17/2018 11:36:40"
TIME2="08/17/2018 12:37:42"
SEC1=`date +%s -d "${TIME1}"`
SEC2=`date +%s -d "${TIME2}"`
DIFF=`expr ${SEC2} - ${SEC1}`

CONVERTTIME() {
  brief=false
  [[ $1 = "-b" ]] && shift && brief=true

  ((w=${1}/604800))
  ((d=(${1}%604800)/86400))
  ((h=(${1}%86400)/3600))
  ((m=(${1}%3600)/60))
  ((s=${1}%60))

  narrative=()
  list[0]="$w week"
  list[1]="$d day"
  list[2]="$h hour"
  list[3]="$m minute"
  list[4]="$s second"
  for (( component=0; $component < ${#list[@]}; ++component )); do
      # Strip the verbage to get the number
      val="${list[$component]/ [a-z]*}"
      if [[ "$val" -gt 0 ]]; then
          if [[ "$val" -gt 1 ]]; then
              list[$component]+='s'
          fi
          narrative+=( "${list[$component]}" )
      fi
  done

  if $brief; then
      if [[ ${#narrative[@]} -eq 0 ]]; then
          echo "Now"
      else
          echo "About ${narrative[0]} ago"
      fi
  else
      if [[ ${#narrative[@]} -eq 0 ]]; then
          echo "Now"
      elif [[ ${#narrative[@]} -eq 1 ]]; then
          echo "${narrative[0]} ago"
      elif [[ ${#narrative[@]} -eq 2 ]]; then
          echo "${narrative[0]} and ${narrative[1]} ago"
      else
          for (( index=0; $index < $((${#narrative[@]}-1)); ++index )); do
              echo -n "${narrative[$index]}, "
          done
          echo "and ${narrative[$(( ${#narrative[@]}-1))]} ago"
      fi
  fi
}
echo
echo "TIME DIFFERENCE: $(CONVERTTIME $DIFF)"
echo

예를 들어:

~ > CONVERTTIME 45
45 seconds ago
~ > CONVERTTIME 65
1 minute and 5 seconds ago
~ > CONVERTTIME 13985
3 hours, 53 minutes, and 5 seconds ago
~ > CONVERTTIME 139854
1 day, 14 hours, 50 minutes, and 54 seconds ago
~ > CONVERTTIME -b 139854
About 1 day ago

관련 정보