UNIX (não-posix) dia do ano a partir da data fornecida?

1

Eu tenho procurado por uma solução existente para obter o dia do ano (não a data juliana) de uma data existente em plataformas UNIX.

Tenho certeza de que existe, mas ainda não o encontrei e não tenho certeza da matemática para obter resultados precisos enquanto contabilizo anos bissextos, etc.

    
por jas- 09.08.2016 / 12:59

5 respostas

-2

Obrigado a todos por suas respostas, mas parece que a matemática do Solaris 10 teria que ser implementada para conseguir isso.

Eu decidi lidar com isso de outra maneira usando o bash & bc para calcular o dia juliano do ano. A fórmula é descrita aqui . A função original pode ser encontrada aqui

A função modificada abaixo pode fazer a conversão e você pode comparar duas datas.

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)
}

Exemplo de uso:

[ $(expr $(conv_date_to_julian 31 12 2017) - $(conv_date_to_julian)) -gt 30 ] && echo true
    
por 11.08.2016 / 12:51
1

Sua tag diz solaris , então presumo que essa seja a plataforma em que você está trabalhando.

Se você tem uma instalação padrão do Solaris 11, é provável que você tenha gdate instalado

Na minha instalação:

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

Para que você possa usar o sinalizador GNUdate -d :

por exemplo

% gdate +%j
222

% gdate -d "1970/06/23" +%j         
174
    
por 09.08.2016 / 13:10
0

Se você tem python instalado:

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

ou se você tiver a data em uma variável de ambiente:

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

(você tem que adaptar o %Y-%m-%d para poder analisar diferentes formatos).

Ambos fornecem 222 como saída.

    
por 09.08.2016 / 13:05
0

No Solaris 11 (onde /bin/sh e /bin/ksh são baseados em ksh93 ):

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

Para o Solaris 10 e versões anteriores, você sempre pode usar perl :

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

POSIXly (e assim UNIXly, bem como a conformidade com o UNIX implica conformidade POSIX), você poderia usar as funções POSIX sh (cuidado com o Solaris, o POSIX / UNIX sh está em /usr/xpg*/bin/sh ) em link :

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

(cuidado com a solução perl , é 0-padded (1 é 001), %-j para remover o preenchimento não suportado (é suportado nas versões recentes de perl , mas não no muito antiga 5.8.4 encontrada no Solaris 10), mas você pode adaptar essas funções para remover o preenchimento.

O próprio número do dia juliano está em $T_J :

$ echo "$T_J"
2457609
    
por 09.08.2016 / 14:07
-1

Para referência, uma reescrita de seu conv_date_to_julian usando a sintaxe Bourne em oposição à sintaxe zsh (assim funcionaria com os shells enviados por padrão no Solaris 10 como o shell Bourne em /usr/bin/sh , ou shell POSIX em /usr/xpg4/bin/sh ou /usr/bin/ksh ), para retornar o número do dia juliano (o número de dias desde 1º de janeiro de 4713 aC, calendário juliano proléptico, não o que você pediu ) e executando menos comandos e com menos bugs:

conv_date_to_julian()
{
  date +"
    d = ${1:-%d}
    m = ${2:-%m}
    y = ${3:-%Y}

    if (m <= 2) {
      m += 12
      y--
    }

    j = 2 - y / 100 + y / 400
    j = (j + 365.25 * (y + 4716)) / 1
    j = (j + 30.6001 * (m + 1)) / 1
    (j + d - 1524.5) / 1" | bc
}
    
por 22.08.2016 / 07:27

Tags