🙏 Helfen Sie jetzt mit, unser LibreOffice Forum zu erhalten! 🙏
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱

🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀

❤️ DANKE >> << DANKE ❤️

>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗

String zu datetime

Alles zur Programmierung im LibreOffice.
Antworten
StefKe
Beiträge: 62
Registriert: Sa 5. Nov 2022, 18:47

String zu datetime

Beitrag von StefKe » So 21. Jul 2024, 21:28

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

Benutzeravatar
karolus
* LO-Experte *
Beiträge: 2536
Registriert: Fr 10. Dez 2010, 10:01

Re: String zu datetime

Beitrag von karolus » So 21. Jul 2024, 23:51

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)
LO7.4.7.5 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.0.3 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)

StefKe
Beiträge: 62
Registriert: Sa 5. Nov 2022, 18:47

Re: String zu datetime

Beitrag von StefKe » Mo 22. Jul 2024, 07:44

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

Benutzeravatar
karolus
* LO-Experte *
Beiträge: 2536
Registriert: Fr 10. Dez 2010, 10:01

Re: String zu datetime

Beitrag von karolus » Di 5. Nov 2024, 10:27

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)
LO7.4.7.5 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.0.3 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)


An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:


Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.



Antworten