wake-up-neo.com

Extrahiere den Tag des Jahres und den Julianischen Tag aus einem String-Datum

Ich habe einen String "2012.11.07" in Python. Ich muss es in Date-Objekt konvertieren und dann einen ganzzahligen Wert von Tag des Jahres und auch Julianischer Tag erhalten. Ist es möglich?

21
f.ashouri

Erstens können Sie es in ein datetime.datetime Objekt wie folgt konvertieren:

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

Dann können Sie die Methoden auf datetime verwenden, um das zu erhalten, was Sie möchten… mit der Ausnahme, dass datetime nicht die gewünschte Funktion hat, die Sie direkt benötigen. Sie müssen also in eine time-Tuple

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

Der Begriff "julianischer Tag" hat einige unterschiedliche Bedeutungen. Wenn Sie nach 2012312 suchen, müssen Sie dies indirekt tun, z. B. eine der folgenden.

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

Wenn Sie nach einer anderen Bedeutung suchen, sollten Sie diese hier herausfinden können. Wenn Sie beispielsweise die Bedeutung "Tage seit dem 1. Januar 4713 v. Chr." Haben möchten und Sie eine Formel haben, die das Gregorianische Jahr und den Tag im Jahr erfordert, müssen Sie die beiden oben genannten Werte verwenden. (Wenn Sie eine Formel dafür haben benötigt Gregorianisches Jahr, Monat und Tag, Sie brauchen nicht einmal den Schritt timetuple.) Wenn Sie nicht herausfinden können, wohin Sie gehen sollen, fragen Sie nach weiteren Details.

Wenn Sie keine Formel haben - und vielleicht sogar, wenn Sie es bereits tun - ist es am besten, PyPI und ActiveState nach bereits vorhandenen Modulen zu durchsuchen. Beispielsweise wurde bei einer Schnellsuche etwas namens jdcal gefunden. Ich hatte es noch nie zuvor gesehen, aber einen kurzen pip install jdcal und eine kurze Überarbeitung der Readme-Datei, und ich konnte dies tun:

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

Das ist das gleiche Ergebnis, das mir der USN Julianische Datumsumrechner gegeben hat.

Wenn Sie einen ganzheitlichen julianischen Tag anstelle eines unvollständigen julianischen Datums wünschen, müssen Sie entscheiden, in welche Richtung Sie abrunden möchten - in Richtung 0, in Richtung negativer Unendlichkeit. Der Mittag wird auf den nächsten Tag gerundet, der Mittag wird auf gerade Tage usw. gerundet Das julianische Datum ist seit dem 1. Januar 4713 v. Chr. Am Mittag definiert. Die Hälfte des 7. Nov. 2012 ist 2456238, die andere Hälfte ist 2456239, und nur Sie wissen, welche davon gewünscht wird ...) Zum Beispiel, um auf 0 zu runden:

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

Um die ersten Schritte der Antwort von abarnert zu vereinfachen:

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

wenden Sie dann den Rest von Abanerts Antwort an.

3
K.-Michael Aye

Diese Funktionalität (Konvertierung von Datumsangaben in julianisches Datum/Uhrzeit) ist auch im Modul Astropy vorhanden. Weitere Informationen finden Sie in deren Dokumentation . Die Astropieimplementierung ist besonders für einfache Konvertierungen in Julian time nützlich, im Gegensatz zu nur dem Julian date.

Beispiellösung für die ursprüngliche Frage:

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

Um den julianischen Tag zu erhalten, verwenden Sie die datetime.date.toordinal-Methode und fügen Sie einen festen Versatz hinzu.

Der julianische Tag ist die Anzahl der Tage seit dem 1. Januar 4713 v. Chr. Um 12:00 Uhr im proleptischen Julianischen Kalender oder der 24. November 4714 v. Chr. Um 12:00 Uhr im proleptischen gregorianischen Kalender . Beachten Sie, dass jeder julianische Tag um Mittag beginnt und nicht um Mitternacht.

Die Funktion toordinal gibt die Anzahl der Tage seit dem 31. Dezember 1 v. Chr. Um 00:00 Uhr im proleptischen Gregorianischen Kalender zurück (mit anderen Worten, der 1. Januar um 1:00 Uhr um 00:00 ist der Beginn von Tag 1, nicht Tag 0). Beachten Sie, dass 1 v. Chr. Direkt vor 1 n. Chr. Liegt. Es gab kein Jahr 0, da die Zahl Null erst viele Jahrhunderte später erfunden wurde.

import datetime

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

Addiere einfach 1721424.5 zum Ergebnis von toordinal, um den Julianischen Tag zu erhalten.

In einer anderen Antwort wurde bereits erläutert, wie Sie den String, mit dem Sie begonnen haben, parsen und in ein datetime.date-Objekt verwandeln. So können Sie den Julianischen Tag wie folgt finden:

import datetime

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

Für schnelle Berechnungen können Sie den Tag des Jahres und die Julianische Tagesnummer nur mit dem Modul stdlib datetime finden:

#!/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

Eine andere Möglichkeit, day_of_year zu erhalten:

import time

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

julian_day im obigen Code ist "die julianische Tagesnummer, die dem Solartag zugeordnet ist - die einem Tag zugewiesene Nummer in einer fortlaufenden Anzahl von Tagen, beginnend mit der julianischen Tagesnummer 0, die dem Tag zugeordnet wird, der ab Greenwich beginnt, bedeutet Mittag am 1. Januar 4713 v. Chr., Julianischer proleptischer Kalender -4712 " .

Die Dokumentation des Moduls time verwendet den Begriff "Julianischer Tag" anders:

Jn Der julianische Tag n (1 <= n <= 365). Sprungtage werden nicht gezählt, also in Alle Jahre 28. Februar ist Tag 59 und 1. März Tag 60.
n Die Julianischer Tag auf Null-Basis (0 <= n <= 365). Sprungtage werden gezählt und es Es ist möglich, sich auf den 29. Februar zu beziehen.

d.h. der nullbasierte Julianische Tag ist hier day_of_year - 1. Die erste (Jn) ist day_of_year - (calendar.isleap(dt.year) and day_of_year > 60) - die Tage ab dem 1. März werden verschoben, um den Schalttag auszuschließen.

Es gibt auch einen verwandten Begriff: Julianisches Datum .Julianische Tagesnummer ist eine Ganzzahl. Julianisches Datum ist von Natur aus fraktional: "Das Julianische Datum (JD) eines beliebigen Augenblicks ist die Julianische Tagesnummer für den vorangegangenen Mittag plus den Bruchteil des Tages seit diesem Moment."

Um zu vermeiden, dass Edge-Fälle selbst gehandhabt werden, verwenden Sie eine Bibliothek, um den Julianischen Tag als von @abarnert empfohlen - zu berechnen.

2
jfs

Gemäß diesem Artikel gibt es eine nicht veröffentlichte einzeilige Formel, die von Fliegel und Van Flandern erstellt wurde, um ein Gregorianisches Datum zu einem Julianischen Datum zu berechnen:

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

Dies wurde von P. M. Muller und R. N. Wimberly vom Jet Propulsion Laboratory, Pasadena, Kalifornien, für Termine nach März 1900 kompaktiert:

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

Diese Formeln sind um 0,5 abweichend, ziehen Sie also einfach 0,5 von den Formeln ab.

Verwenden Sie etwas String-Manupulation, um die Daten tatsächlich zu extrahieren, und Sie werden gut sein

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

Von den obigen Beispielen ist hier der eine Liner (nicht 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