Extrair dia do ano e dia juliano de uma data de seqüência

Eu tenho uma string "2012.11.07" em python. Eu preciso convertê-lo para object de data e, em seguida, obter um valor inteiro do dia do ano e também do dia juliano . É possível?

Primeiro, você pode convertê-lo em um object datetime.datetime como este:

 >>> import datetime >>> fmt = '%Y.%m.%d' >>> s = '2012.11.07' >>> dt = datetime.datetime.strptime(s, fmt) >>> dt datetime.datetime(2012, 11, 7, 0, 0) 

Então você pode usar os methods em datetime para obter o que você quer … exceto que o datetime não tem a function que você quer diretamente, então você precisa converter para uma tupla de tempo

 >>> tt = dt.timetuple() >>> tt.tm_yday 312 

O termo “dia juliano” tem alguns significados diferentes. Se você está procurando 2012312 , você tem que fazer isso indiretamente, por exemplo, um dos seguintes.

 >>> int('%d%03d' % (tt.tm_year, tt.tm_yday)) 2012312 >>> tt.tm_year * 1000 + tt.tm_yday 2012312 

Se você está procurando um significado diferente, você deve ser capaz de descobrir isso daqui. Por exemplo, se você quiser que os “dias desde 1º de janeiro de 4713 aC” sejam significados, e você tiver uma fórmula que exija ano e ano gregorianos no ano, você terá esses dois valores acima para ser plugado (se tiver uma fórmula leva ano, mês e dia gregorianos, você nem precisa do passo do timetuple .) Se você não sabe onde ir a partir daí, peça mais detalhes.

Se você não tem uma fórmula – e talvez até mesmo se você já fez – sua melhor aposta é provavelmente olhar ao redor do PyPI e do ActiveState para módulos pré-existentes. Por exemplo, uma pesquisa rápida revelou algo chamado jdcal . Eu nunca tinha visto isso antes, mas um pip install jdcal rápido pip install jdcal e um breve resumo do readme, e eu pude fazer isso:

 >>> sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)) 2456238.5 

Esse é o mesmo resultado que o conversor de data Julian da USN me deu.

Se você quiser um dia juliano integral, em vez de uma data juliana fracionária, você deve decidir qual direção deseja arredondar – em direção a 0, em direção ao infinito negativo, arredondando o meio dia até o dia seguinte, arredondando o meio-dia em dias pares, etc. A data juliana é definida como iniciada a partir de meio-dia em 1 de janeiro de 4713BC, portanto, metade de 7 de novembro de 2012 é 2456238, a outra metade é 2456239 e somente você sabe qual deles deseja…) Por exemplo, para arredondar para 0:

 >>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day))) 2456238 

Para simplificar os passos iniciais da resposta de Abarnert:

 from dateutil import parser s = '2012.11.07' dt = parser.parse(s) 

em seguida, aplique o resto da resposta do abanert.

Esta funcionalidade (conversão de strings de data para data / hora juliana) também está presente no módulo astropy . Por favor, consulte a documentação para obter detalhes completos. A implementação do astropy é especialmente útil para conversões fáceis para o tempo juliano, em oposição a apenas a data juliana.

Exemplo de solução para a pergunta original:

 >>> import astropy.time >>> import dateutil.parser >>> dt = dateutil.parser.parse('2012.11.07') >>> time = astropy.time.Time(dt) >>> time.jd 2456238.5 >>> int(time.jd) 2456238 

Para cálculos rápidos, você pode encontrar o dia do ano e o número do dia Julian usando apenas o módulo stdlib datetime :

 #!/usr/bin/env python3 from datetime import datetime, timedelta DAY = timedelta(1) JULIAN_EPOCH = datetime(2000, 1, 1, 12) # noon (the epoch name is unrelated) J2000_JD = timedelta(2451545) # julian epoch in julian dates dt = datetime.strptime("2012.11.07", "%Y.%m.%d") # get datetime object day_of_year = (dt - datetime(dt.year, 1, 1)) // DAY + 1 # Jan the 1st is day 1 julian_day = (dt.replace(hour=12) - JULIAN_EPOCH + J2000_JD) // DAY print(day_of_year, julian_day) # 312 2456239 

Outra maneira de obter o day_of_year :

 import time day_of_year = time.strptime("2012.11.07", "%Y.%m.%d").tm_yday 

julian_day no código acima é “o número do dia juliano associado ao dia solar – o número atribuído a um dia em uma contagem contínua de dias que começam com o dia juliano número 0 atribuído ao dia que começa em Greenwich significa meio-dia em 1 de janeiro de 4713 BC, calendar proléptico Juliano -4712 ” .

A documentação do módulo de time usa o termo “dia juliano” de forma diferente:

Jn O dia juliano n (1 <= n <= 365). Os dias bissextos não são contados, então, em todos os anos, 28 de fevereiro é o dia 59 e 1º de março é o dia 60.
n O dia juliano baseado em zero (0 <= n <= 365). Os dias bissextos são contados e é possível fazer referência a 29 de fevereiro.

ou seja, o dia juliano com base zero é day_of_year - 1 aqui. E o primeiro ( Jn ) é day_of_year - (calendar.isleap(dt.year) and day_of_year > 60) – os dias que começam em 1 de março são deslocados para excluir o dia bissexto.

Há também um termo relacionado: data juliana . O número do dia juliano é um inteiro. A data juliana é inerentemente fracionária: “A Data Juliana (JD) de qualquer instante é o número do dia juliano para o meio-dia anterior mais a fração do dia desde aquele instante.”

Em geral, para evitar manipular casos de borda, use uma biblioteca para calcular o dia juliano, conforme sugerido por @abarnert .

Para obter o dia juliano, use o método datetime.date.toordinal e adicione um deslocamento fixo.

O dia juliano é o número de dias desde 1º de janeiro de 4713 aC às 12:00 no calendar proletário Juliano, ou 24 de novembro de 4714 aC às 12:00 no calendar gregoriano proléptico . Note que cada dia juliano começa ao meio-dia, não à meia-noite.

A function toordinal retorna o número de dias desde 31 de dezembro, 1 aC às 00:00 no calendar gregoriano proléptico (em outras palavras, 1 de janeiro, 1 AD às 00:00 é o início do dia 1, não o dia 0). Observe que 1 aC precede diretamente 1 DA, não houve ano 0, já que o número zero não foi inventado até muitos séculos depois.

 import datetime datetime.date(1,1,1).toordinal() # 1 

Simplesmente adicione 1721424.5 ao resultado de toordinal para obter o dia juliano.

Outra resposta já explicou como analisar a string que você iniciou e transformá-la em um object datetime.date . Então você pode encontrar o dia juliano da seguinte forma:

 import datetime my_date = datetime.date(2012,11,7) # time = 00:00:00 my_date.toordinal() + 1721424.5 # 2456238.5 

Dos exemplos acima, aqui está o liner (não-juliano):

 import datetime doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday 
 def JulianDate_to_date(y, jd): month = 1 while jd - calendar.monthrange(y,month)[1] > 0 and month <= 12: jd = jd - calendar.monthrange(y,month)[1] month += 1 date = datetime.date(y,month,jd).strftime("%m/%d/%Y") return date 

De acordo com este artigo, há uma fórmula inédita de uma linha criada por Fliegel e Van Flandern para calcular uma data gregoriana para uma data juliana:

 JD = 367 * year - 7 * (year + (month + 9)/12)/4 - 3 * ((year + (month - 9)/7)/100 + 1)/4 + 275 * month/9 + day + 1721029 

Este foi compactado por PM Muller e RN Wimberly do Jet Propulsion Laboratory, Pasadena, Califórnia, para datas após março de 1900 para:

 JD = 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014 

Essas fórmulas estão desativadas em 0,5, portanto, basta subtrair 0,5 das fórmulas.

Use alguma manipulação de strings para extrair os dados e você será bom

 >>> year, month, day = map(int,"2018.11.02".split(".")) >>> 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014 - 0.5 2458424.5 
Intereting Posts