날짜 : 현재 15 분 간격 가져 오기


15

date 명령 또는 이와 유사한 것을 사용하여 현재 15 분 간격을 얻을 수있는 방법이 있습니까?

날짜와 같은 예를 들어 뭔가가 %Y.%m.%d %H:%M 저를 줄 것이다 2011.02.22 10:19, 내가 뭔가를 필요로하는 수익률 2011.02.22 10:15에서 시간 범위에서 10:1510:29.

답변:


17

를 사용하여 현재 유닉스 타임 스탬프를 얻고 date "+%s"간단한 수학 (현재 예제는 bash)으로 현재 분기 시간을 찾고 다음을 사용하여 더 나은 형식으로 다시 인쇄 할 수 있습니다 date.

curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"

@그것은 당신의 OS에서 작동하지 않는 경우 타임 스탬프에서 현재 날짜와 시간을 설정하는 구문은, 날짜에 GNU의 확장자, 당신은 그렇지 않으면,이 같은 동일 (UTC를 지정하는 것을 잊지 마세요 할 수있는, 그것은 '수상 t 일) :

date -d"1970-01-01 $curquarter seconds UTC"

5

다음 방법으로 date두 번 호출 할 필요가 없습니다 .
시스템 호출의 오버 헤드는 자체 로컬 환경에서 동일한 작업을 수행하는 bash보다 "간단한"명령을 100 배 느리게 만들 수 있습니다.

업데이트 위의 주석에 대해 간단히 언급하면 ​​"100 배 더 느립니다". 이제 " 500 배 느리게" 읽을 수 있습니다 ... 최근에이 문제에 빠졌습니다 (맹목적으로 걸었습니다). 다음은 링크입니다. 테스트 파일을 작성하는 빠른 방법

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00  
echo $Y.$m.$d $H:$M  

또는

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if   [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M

두 버전 모두 반환됩니다

2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45   

다음은 모든 60 개 값에 대한 테스트 루프가있는 첫 번째 것입니다 {00..59}

for X in {00..59} ;                         ###### TEST
do                                          ###### TEST 
  eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
  M=$X                                      ###### TEST 
  [[ "$M" < "15" ]] && M=00 # cater for octal clash
  M=$(((M/15)*15))
  ((M==0)) && M=00 # the math returns 0, so make it 00  
  echo $Y.$m.$d $H:$M 
done                                        ###### TEST 

1
간단히 설명하자면 "시스템 호출" 은 일반적으로 시스템 호출 이 아니라 "system () 호출과 같은 포크 / 실행 / 대기"를 의미 합니다. (시스템 호출은 사용자 / 커널 스위치로 인해 프로그램 내에 오버 헤드가 있기 때문에 이것을 언급합니다. 여기서는 특별한 문제가 아닙니다.)
mattdm

mattdm ... 감사합니다. Linux 경험이 6 개월 밖에되지 않아서 잘못된 문구를 사용했을 가능성이 있지만 불필요한 호출로 인해 발생하는 오버 헤드와 내 자신의 테스트 경험에 대해서는 계속 읽습니다. 스크립트, printf또는 호출 또는 sed"불필요한" cat대 <파일이 실제 런타임 차이를 크게 만드는 많은 예를 보았습니다 . 내 "500 배 더 느린"예제 에서처럼 반복 할 때. 가능하면 쉘을 사용하고 date배치 프로세스 와 같은 프로그램을 허용하는 것이 내가 의미하는 것 같습니다. Gilles의 Left-Pad-0 예제, printf
Peter.O

3

쉘에서 날짜를 처리하는 방법은 다음과 같습니다. 먼저 date구성 요소를 가져 와서 구성 요소로 위치 매개 변수 ( $1, $2등)를 채우십시오 ( 이것은 $(…)큰 따옴표 외부 에서 사용 하여 문자열을 단어로 나누려는 드문 경우 중 하나입니다 ). 그런 다음 산술, 테스트 또는 구성 요소에 대해 수행해야하는 모든 작업을 수행하십시오. 마지막으로 구성품을 조립하십시오.

0은 8 진 접두사로 취급하기 때문에 산술 부분은 약간 까다로울 수 있습니다 . 예를 들어 여기서 $(($5/15))시간이 지나면 8 분 또는 9 분에 실패합니다. 최대 하나의 선도 0${5#0}있으므로 산술에 안전합니다. 100을 더한 다음을 제거 1하면 출력에서 ​​고정 자릿수를 얻는 방법입니다.

set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"

"무역의 비결"... 좋은 것. :)
Peter.O

2

아마 더 이상 중요하지 않지만 내 자신의 dateutils 시도 할 수 있습니다. 반올림 (분)은 몇 분으로 끝나고 dround부정적인 주장은 다음과 같습니다.

dround now /-15m
=>
  2012-07-11T13:00:00

또는 형식을 준수하십시오.

dround now /-15m -f '%Y.%m.%d %H:%M'
=>
  2012.07.11 13:00

실제로 유틸리티가 더 이상 어떻게 작동합니까? 내가 시간을지나 가장 가까운 15 분 입력 되감기를 얻을 수 -15m을 사용하여 : dateutils.dround '2018-11-12 13:55' -15m생산 2018-11-12T13:15:00하지 2018-11-12T13:45:00.

1
@JackDouglas 도구가 발전했습니다. 원하는 것은 다음 /-15m과 같습니다 . 즉, 한 시간에 15 분의 다음 배수로 내림합니다. 13 (시간의 분) 60의 약수가 아니기 때문에이 기능은 이하의 값을 받아들이고 있기 때문에 더 복잡 구문을 가지고 / -13m는 인스턴스 불가능
hroptatyr

좋아, 나는 지금 필요한 것을 얻습니다 dateutils.dround '2018-11-12 12:52:31' /450s /-15m. 감사합니다!

2

일부 쉘은 외부 date명령 을 호출하지 않고 작업을 수행 할 수 있습니다 .

a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))

위의 세 가지는 UTC가 아닌 현지 시간을 제공합니다. 필요한 경우 선행 TZ = UTC0을 사용하십시오.

ksh 및 bash 구문은 거의 동일합니다 ( #ksh 에서 필수 제외 ). zsh는 모듈을로드해야합니다 (zsh 배포에 포함).

(GNU) awk로도 가능합니다 :

awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'

로컬이 필요한 경우 UTC 결과를 제공합니다 (마지막 1을로 변경 0). 그러나 외부 awk 또는 외부 zsh 모듈을로드하면 호출 날짜 자체보다 느릴 수 있습니다.

a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

작은 실행 파일도 busybox비슷한 결과를 제공 할 수 있습니다.

a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

busybox가 PATH 디렉토리의 해당 이름에 링크 된 경우 선행 busybox 단어를 생략 할 수 있습니다.

모두 datebusybox date위의 UTC 시간을 인쇄합니다. -u현지 시간에 대한 옵션을 제거하십시오 .


운영 체제에 더 제한된 버전의 날짜가 있고 사용해야하는 경우 다음을 시도하십시오.

a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'

또는 FreeBSD라면 다음을 시도하십시오.

a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'

1

호출 날짜를 두 번 살 수있는 경우 Solaris의 bash에서 작동합니다.

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"

의견을 대신하여 다음을 수정했습니다.

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'

1
시간의 제 qurarter, 이것은 단지 하나의 0 대신 00 분간 함께 출력을 생성 할 것이다
Peter.O

수정, 원래 명령 후 간단한 sed입니다.
ddeimeke

하나 더 버그 : 그것은 H : 08과 H : 10 사이에서 작동하지 않습니다. 이유와 수정 사항에 대한 내 답변 을 참조하십시오 .
Gilles 'SO- 악의를 멈춰라'

-1

정확한 요구 사항이 확실하지 않습니다. 그러나 15 분 후에 시간을 생성하려면과 같은 것을 사용할 수 있습니다 date -d '+15 min'. 출력은 아래와 같습니다 :

$ date; date  -d '+15 min'
Tue Feb 22 18:12:39 IST 2011
Tue Feb 22 18:27:39 IST 2011

1
당신은 그 질문을 오해했습니다. 요점은 날짜 (아래로)를 15 분의 배수로 반올림하는 것입니다.
Gilles 'SO- 악마 중지'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.