UNIX(non-posix) 제공된 날짜를 기준으로 연중 몇일이 됩니까?

UNIX(non-posix) 제공된 날짜를 기준으로 연중 몇일이 됩니까?

저는 UNIX 플랫폼의 기존 날짜에서 연도별 날짜(율리우스력 날짜 아님)를 가져오는 기존 솔루션을 찾고 있었습니다.

존재한다고 확신하지만 아직 찾지 못했고 윤년 등을 계산할 때 정확한 결과를 수행하는 수학이 확실하지 않습니다.

답변1

귀하의 레이블에 그렇게 나와 solaris있으므로 귀하가 사용하고 있는 플랫폼이 바로 이것이라고 가정합니다.

Solaris 11의 표준 설치가 있는 경우 다음을 gdate설치 했을 수 있습니다.

내 설치에서 :

lrwxrwxrwx   1 root     root          15 Aug  3 13:21 /usr/bin/gdate -> ../gnu/bin/date*

따라서 GNUdate 플래그를 사용할 수 있습니다 -d:

예를 들어

% gdate +%j
222

% gdate -d "1970/06/23" +%j         
174

답변2

Python이 설치되어 있는 경우:

python -c 'import datetime; d=datetime.date(2016, 8, 9); print(d.timetuple().tm_yday)'

또는 환경 변수에 날짜가 있는 경우:

DATE=2016-08-09
python -c 'import datetime; d=datetime.strptime("'"$DATE"'", "%Y-%m-%d"); print(d.timetuple().tm_yday)'

(다른 형식을 구문 분석하려면 조정해야 합니다 %Y-%m-%d).

둘 다 출력으로 제공됩니다 222.

답변3

Solaris 11( 및 /bin/sh기반 /bin/ksh) ksh93:

$ /bin/ksh -c 'printf "%(%-j)T\n" 2016-01-01 2016-08-09'
1
222

Solaris 10 및 이전 버전의 경우 언제든지 다음을 사용할 수 있습니다 perl.

$ perl -MPOSIX -le '($y,$m,$d)=@ARGV;
                    print strftime "%j", 0,0,0, $d,$m-1,$y-1900
                   ' 2016 8 9
222

POSIXly(따라서 UNIX 및 UNIX 준수는 POSIX 준수를 의미함) 이러한 POSIX 기능을 사용할 수 있습니다 sh(Solaris에서는 POSIX/ UNIX sh/usr/xpg*/bin/shhttps://raw.githubusercontent.com/stephane-chazelas/misc-scripts/master/wide_strftime.sh:

$ timegm 2016 08 09 && wide_strftime '' "$REPLY" && echo "$T_j"
222

( perl솔루션과 마찬가지로 0 패딩(1은 001)이며 %-j패딩 제거는 지원되지 않습니다(최신 버전에서는 지원되지만 perlSolaris 10에 있는 아주 오래된 5.8.4 버전에서는 지원되지 않음). 이 기능을 조정하여 패딩을 제거할 수 있습니다.)

율리우스력 날짜 자체는 다음 위치에 있습니다 $T_J.

$ echo "$T_J"
2457609

답변4

답변해 주신 모든 분들께 감사드립니다. 하지만 이를 달성하려면 Solaris 10에서 수학을 구현해야 하는 것 같습니다.

나는 이 문제를 다른 방법으로 해결하기로 결정했습니다. 그것은 bash & bc를 사용하여 연중 율리우스력 날짜를 계산하는 것입니다. 공식은 설명합니다여기. 원래 기능을 찾을 수 있습니다여기

아래 수정된 함수는 변환을 수행한 다음 두 날짜를 비교할 수 있습니다.

function conv_date_to_julian()
{
  local cdate="$(date +%d:%m:%Y)"

  local day="${1:=$(echo ${cdate} | cut -d: -f1)}"
  local month="${2:=$(echo ${cdate} | cut -d: -f2)}"
  local year="${3:=$(echo ${cdate} | cut -d: -f3)}"
  local jdoy

  if [ ${month} -le 2 ]; then
    year=$(( ${year} - 1))
    month=$(( ${month} + 12))
  fi

  jdoy=$(echo "2 - ${year} / 100 + ${year} / 400" | bc)
  jdoy=$(echo "(${jdoy} + 365.25 * (${year} + 4716))/1" | bc) 
  jdoy=$(echo "(${jdoy} + 30.6001 * (${month} + 1))/1" | bc)

  echo $(echo "(${jdoy} + ${day} - 1524.5)" | bc)
}

사용 예:

[ $(expr $(conv_date_to_julian 31 12 2017) - $(conv_date_to_julian)) -gt 30 ] && echo true

관련 정보