
나는 때때로 이 date
명령을 사용하여 ISO-8601 요일 달력을 기반으로 현재 또는 미래 날짜의 주 번호를 확인합니다. 이를 수행하려면 다음을 사용하면 됩니다. date +%V
현재 ISO 주 번호를 확인하고 date -d "2021-12-25" +%V
다른 날짜(이 경우 크리스마스)의 ISO 주 번호를 확인합니다.
그러나 이를 반대로 하는 것은 불가능해 보입니다. 즉, "주 번호" 형식의 날짜가 주어지면 "월-날짜" 형식의 날짜를 가져옵니다. 예를 들어 를 실행하면 date -d "2021-W50-3"
해당 형식이 지원되지 않는다는 오류가 발생합니다. 왜 안 돼? 이 형식을 사용하여 날짜를 입력하거나 저장할 수 있는 방법이 있습니까?
답변1
GNU에는 date
비표준 옵션이 있으며 (및 온라인 -d
에 문서화된) 제한된 날짜/시간 형식 세트만 지원합니다.info date 'Date input formats'
여기).
date
더 많은 날짜 형식(참조하는 형식 포함)을 지원하는 구현 의 경우 from 구현을 사용할 수 있습니다( date
GNU 와 같은 ast-open
입력 날짜 에서도 작동함).-d
date
(그러나 그런 경우는 거의 없음)의 일부로 빌드된 경우 date
ksh93 쉘의 내장 일 수도 있고 ast-open
대신 내장(항상 포함됨) 및 지정자( 시간은 없지만 구문 분석된 부분은 복사됨)를 date
사용할 수 있습니다 . :printf
%T
bash
$ builtin date
$ date -d '2021-W50-3' +%F
2021-12-15
$ printf '%(%F)T\n' 2021-W50-3
2021-12-15
bash
쉘(또는 다른 쉘) 에서는 언제든지 다음을 수행할 수 있습니다.
$ ksh93 -c '"${@:0}"' printf '%(%F)T\n' 2021-W50-3
2021-12-15
그러나 시스템에 따라 ksh93은 호출되거나(또는 Solaris 11+에서와 같이, There라고도 함) 전혀 호출되지 않을 수 있습니다 ksh
. ksh2020
ksh93 sh
( ksh
예: bash 또는 zsh) 시스템은 기본적으로 설치되지 않습니다. 모든 시스템에서.
참고하시기 바랍니다.기준strftime()
이 표준 형식의 날짜는 사양 %G-%V-%u
및 해당 표준 기능 에 따라 생성될 수 있습니다.분석하다타임스탬프(strptime()
)는 지원하지도 않으며 %G
지원 %V
하지도 않습니다.표준 유닉스getdate()
).
GNU는 strptime()
현재 이를 표준에 대한 확장으로 이해하지만 무시하도록 문서화되어 있습니다(참조info libc strptime
).FreeBSDstrptime()
동일한 지시문이 지원된다고 문서화되어 있지만 FreeBSD 12.2( 내장 strftime()
사용)에 대한 테스트에서는 작동하지 않는 것 같습니다.zsh
strftime -r
그러나 POSIX, GNU 및 freebsd는 strptime()
이를 지원합니다 %W
.
zsh
:$ strftime -rs t %Y-W%W-%u 2021-W50-3 && strftime %F $t 2021-12-15
busybox
:$ busybox date -D %Y-W%W-%u -d 2021-W50-3 +%F 2021-12-15
%Y-%W
동일하지는 않지만 %G-%V
이 경우에는 우연의 일치입니다. %W
1월 1일은 00이며 월요일인 경우에는 01입니다. 그리고 %V
(ISO 주 번호)는 해당 주의 일수가 전년도 또는 올해에 더 있는지에 따라 해당 연도의 첫 번째 주(01) 또는 전년도의 마지막 주(52 또는 53)입니다.
답변2
정확한 ISO 주 날짜(이전 또는 다음 해로의 롤오버 포함)는 두 가지 실행을 사용하여 얻을 수 있습니다 date
. 하나는 알려진 날짜(저는 6월 1일을 선택했습니다)로 보정하고 다른 하나는 ISO 주/일 차이를 숫자별로 조정합니다. 일. 이는 윤년의 영향을 받지 않습니다. 이것이 월 대신 ISO 주를 사용하는 요점입니다.
이 함수는 2021-W50-3 형식을 2021-12-15로 변환하고 연도 반전을 표시하는 테스트를 수행합니다.
#! /bin/bash
isoDate () {
declare -a dR #.. Required date
declare -a dC #.. Calibration date.
printf 1>&2 '\nAsked %s\n' "${1}" #debug
IFS='-' read -a dR <<<"${1}"
IFS='-' read -a dC <<<"$( date -d "${dR[0]}-06-01" '+%G-W%V-%u' )"
dR[1]=${dR[1]#W}; dR[1]=${dR[1]#0}
dC[1]=${dC[1]#W}; dC[1]=${dC[1]#0}
declare Adj=$(( 7 * (${dR[1]} - ${dC[1]}) + ${dR[2]} - ${dC[2]} ))
date -d "${dR[0]}-06-01 + ${Adj} days" '+%Y-%m-%d'
}
Ymd=$( isoDate '2021-W50-3' )
printf 'Found %s\n' "${Ymd}"
date -d "${Ymd}" '+Check %G-W%V-%u'
Ymd=$( isoDate '2020-W01-1' )
printf 'Found %s\n' "${Ymd}"
date -d "${Ymd}" '+Check %G-W%V-%u'
Ymd=$( isoDate '2011-W52-7' )
printf 'Found %s\n' "${Ymd}"
date -d "${Ymd}" '+Check %G-W%V-%u'
결과:
$ ./isoDate
Asked 2021-W50-3
Found 2021-12-15
Check 2021-W50-3
Asked 2020-W01-1
Found 2019-12-30
Check 2020-W01-1
Asked 2011-W52-7
Found 2012-01-01
Check 2011-W52-7
$