Seite 1 von 1

String zu datetime

Verfasst: So 21. Jul 2024, 21:28
von StefKe
Hallo in die Runde, ich versuche grad die Konvertierung eines Strings zu Float als Datum/Zeitwert in eine Tabelle einzutragen:

Code: Alles auswählen

from datetime import datetime
def str_to_datetime():
    date_time = "2024-07-21T17:02:47Z"
    oDoc = XSCRIPTCONTEXT.getDocument()
    sheet = oDoc.Sheets[0]
    date_time = datetime.strptime(date_time,'%Y-%m-%dT%H:%M:%SZ')
    delta_time = datetime(1899,12,29,21,19,0)
    time_value = date_time - delta_time
    sheet[0,0].Value = float(f"{time_value.days}.{time_value.seconds}")    

if __name__ == "__main__":
    str_to_datetime()
prinzipell erfüllt das Script seinen Zweck, aber es geht sicherlich auch einfacher, oder?

Den Wert für delta_time hab ich so getestet und der passt auch. Aber eigentlich rechnet doch LO ab dem 31.12.1899, was dem Wert 1 entspricht. Warum dann dieser 'krumme' Wert?

Danke - Stefan

Re: String zu datetime

Verfasst: So 21. Jul 2024, 23:51
von karolus
hallo
Falls da schon ein Date_time_string (beinahe ) im ISO-Format vorliegt, kannst du pragmatisch Calc die Umrechnung überlassen:

Code: Alles auswählen

stamp = "2024-07-21T17:02:47Z"
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
sheet[0,0].FormulaLocal = stamp.replace("T"," ")[:-1]
mit …FormulaLocal übernimmt Calc auch gleich implizit die Formatierung.
mit …Formula würde zunächst als Fliesskomma formatiert werden.
______________________

Deine Umrechnung passt anfangs schon, aber spätestens bei dem krummen Wert für die LO-epoche, und bei der Übergabe der Sekunden in die float-berechnung machst du Unsinn, da müsste ja jeder Tag aus 100000Sekunden bestehen und die Sekundenanzahl auch ggf fünf-stellig mit führenden Nullen dargestellt werden.
Eine richtige Umrechnung sieht etwa so aus:

Code: Alles auswählen

from datetime import datetime as dt , timedelta

stamp = "2024-07-21T17:02:47Z"

py_date = dt.strptime(stamp ,'%Y-%m-%dT%H:%M:%SZ')
lo_epoch = dt(1899,12,30)
delta = py_date - lo_epoch
lo_date = delta.days + delta.seconds/86400 # 24*60*60 Sekunden/Tag
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]

sheet[2,0].Value = lo_date
_________

Die umgekehrte Berechnung eines DateTime-objekts aus einem Calc-datum wäre:

Code: Alles auswählen

lo_date = sheet[2,0].Value
date, frac = divmod(lo_date, 1)
ordinal = int(lo_epoch.toordinal() + date)
py_date = dt.fromordinal(ordinal) + timedelta(seconds= frac*86400)
print(py_date)

Re: String zu datetime

Verfasst: Mo 22. Jul 2024, 07:44
von StefKe
Danke, das hilft. Die Verwendung von timedelta hatte ich auch versucht, bin aber an der Addition von Tagen und Sekunden gescheitert. Manchmal sind es eben richtig große Balken vorm Kopf ;)
Das Zeitformat wird von Thingspeak so geliefert. Ich vermute, dass das Z am Stringende die Zeitzone definiert - muss mich da in der API noch kundig machen.
So schaut der Code logischer aus - Danke.

Stefan

Re: String zu datetime

Verfasst: Di 5. Nov 2024, 10:27
von karolus
Hallo
karolus hat geschrieben:Die umgekehrte Berechnung eines DateTime-objekts aus einem Calc-datum wäre:

Code: Alles auswählen

lo_date = sheet[2,0].Value
date, frac = divmod(lo_date, 1)
ordinal = int(lo_epoch.toordinal() + date)
py_date = dt.fromordinal(ordinal) + timedelta(seconds= frac*86400)
print(py_date)
Eigentlich etwas umständlich, es geht auch einfacher:

Code: Alles auswählen

lo_date = sheet[2,0].Value
lo_epoch = dt(1899,12,30)
py_date = lo_epoch + timedelta(days=lo_date)
print(py_date)