web-dev-qa-db-fra.com

Extrait le jour de l'année et le jour julien d'une date de chaîne

J'ai une chaîne "2012.11.07" en python. Je dois le convertir en objet date et obtenir ensuite une valeur entière de jour de l'année et aussi jour Julien . C'est possible?

21
f.ashouri

Tout d'abord, vous pouvez le convertir en un objet datetime.datetime comme ceci:

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

Ensuite, vous pouvez utiliser les méthodes sur datetime pour obtenir ce que vous voulez… sauf que datetime n'a pas la fonction que vous voulez directement, vous devez donc convertir en un time Tuple

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

Le terme "jour julien" a plusieurs significations différentes. Si vous recherchez 2012312, vous devez le faire indirectement, par exemple l’un des suivants.

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

Si vous cherchez un sens différent, vous devriez pouvoir le comprendre à partir d'ici. Par exemple, si vous voulez la signification de "jours depuis le 1 er janvier 4713 av. J.-C." et que vous avez une formule qui nécessite année et jour grégoriens, vous devez vous connecter aux deux valeurs ci-dessus. (Si vous avez une formule qui prend année grégorienne, mois et jour, vous n'avez même pas besoin de l'étape timetuple.) Si vous ne savez pas où aller à partir de là, demandez plus de détails.

Si vous n'avez pas de formule, et peut-être même si vous en avez déjà une, votre meilleur choix est probablement de rechercher dans PyPI et ActiveState des modules préexistants. Par exemple, une recherche rapide a mis en évidence un élément appelé jdcal . Je ne l'avais jamais vu auparavant, mais un rapide pip install jdcal et un bref survol du fichier Lisez-moi, et j'ai été capable de le faire:

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

C'est le même résultat que le convertisseur de date USN Julian m'a donné.

Si vous voulez le jour julien intégral, au lieu de la date julienne fractionnaire, vous devez décider quelle direction vous souhaitez arrondir - vers 0, vers l'infini négatif, arrondissant midi au lendemain, arrondissant midi aux jours pairs, etc. La date de Julien est définie comme commençant depuis midi le 1er janvier 4713 av. J.-C., si bien que la moitié du 7 novembre 2012 est 2456238, l'autre moitié est 2456239, et que vous savez laquelle de celles que vous voulez…) Par exemple, arrondir à 0:

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

Pour simplifier les premières étapes de la réponse d'abarnert:

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

appliquez ensuite le reste de la réponse d'abanert.

3
K.-Michael Aye

Cette fonctionnalité (conversion des chaînes de date en date/heure en julien) est également présente dans le module astropy . Veuillez vous référer à leur documentation pour plus de détails. L’application astropy est particulièrement pratique pour les conversions faciles en Julian time, par opposition à Julian date.

Exemple de solution pour la question initiale:

>>> 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
3
Kyle

Pour des calculs rapides, vous pouvez trouver le jour de l’année et le numéro du jour julien en utilisant uniquement le module 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

Une autre façon d’obtenir day_of_year:

import time

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

julian_day dans le code ci-dessus est "le numéro du jour julien associé au jour solaire - le numéro attribué à un jour dans un décompte continu de jours commençant par le jour julien numéro 0 attribué au jour commençant à Greenwich signifiant midi le 1 Janvier 4713 av. J.-C., calendrier proleptique Julian -4712 " .

La documentation du module time utilise le terme "jour julien" différemment:

Jn Le jour julien n (1 <= n <= 365). Les jours bissextiles ne sont pas comptés, alors dans toutes les années le 28 février est le jour 59 et le 1er mars est le jour 60.
n Le jour julien de base zéro (0 <= n <= 365). Les jours bissextiles sont comptés, et cela est possible de se référer au 29 février.

c'est-à-dire que le jour julien de base zéro est day_of_year - 1 ici. Et le premier (Jn) est day_of_year - (calendar.isleap(dt.year) and day_of_year > 60) - les jours commençant le 1er mars sont décalés pour exclure le jour bissextile.

Il existe également un terme apparenté: date du Julien.numéro du jour du Julien est un entier. Date julienne est intrinsèquement fractionnaire: "La date julienne (JD) de tout instant est le numéro du jour Julien pour le midi précédent, plus la fraction du jour depuis cet instant. "

En général, pour éviter de manipuler vous-même les cas Edge, utilisez une bibliothèque pour calculer le jour julien comme suggéré par @abarnert .

2
jfs

Selon cet article , il existe une formule non publiée à une ligne créée par Fliegel et Van Flandern pour calculer une date grégorienne en une date en Julien:

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

Ceci a été compacté par P. M. Muller et R. N. Wimberly du laboratoire de propulsion par jet de Pasadena, Californie, pour des dates postérieures à mars 1900:

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

Ces formules sont désactivées de 0,5, il suffit donc de soustraire 0,5 des formules.

Utilisez une manipulation de chaîne pour extraire réellement les données et vous serez bien

>>> 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
0
FGol

Parmi les exemples ci-dessus, voici le liner (non Julian):

import datetime

doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday
0
nvd
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
0
Mounirsky