Zeiten als String addieren...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

Hallo,
ich muss Strings, die eine Zeit im Format '%H:%M:%S' abbilden, wertmäßig um n Minuten erhöhen/verringern

Die Variablen heißen:
als String
log_start_time_str
log_end_time_str
log_mid_time_str
und im Zeitformat:
log_start_time
log_end_time
log_mid_time

Ich wollte zuerst die Strings in eine Zeitinfo umwandeln, dann datetime.timedelta(minutes = x) hinzuaddieren, dann wieder die angepasste Zeitinfo in Strings zurückwandeln.

Code: Alles auswählen

log_start_time_str = input ('Please enter log start time (hh:mm:ss) :')
log_start_time = time.strptime(log_start_time_str, '%H:%M:%S')
log_end_time = log_start_time + datetime.timedelta(minutes = 6)
log_end_time_str = strftime('%H:%M:%S')
log_mid_time = log_start_time + datetime.timedelta(minutes = 3)
log_mid_time_str = strftime('%H:%M:%S')
bei >log_end_time = log_start_time + datetime.timedelta(minutes = 6) und ff. gibt es ein Fehler:
Python will hier ein Concatenate machen und sieht 2 unterscheidlichen Datentypen...
TypeError: can only concatenate tuple (not "datetime.timedelta") to tuple

Wie bekommt man das hin?
Beispiele mit "datetime.timedelta(minutes = n)" gibt es nur mit datetime.datetime(now), nicht mit eine beliebige Zeit.

Oder muss man anders vorgehen?
Die Zeitinfos brauche ich am Ende als String, nicht als Epochzeit.

Danke
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Hinter den Funktionsaufruf kommt kein Leerzeichen in der ersten Zeile.

Du willst datetime.datetime.strptime() wenn du so vorgehen möchtest.

Dass dieses nackte Aufrfufen von strftime nicht funktioniert, ist dir klar?
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

sparrow hat geschrieben: Sonntag 15. März 2020, 00:31 Hinter den Funktionsaufruf kommt kein Leerzeichen in der ersten Zeile.
Du willst datetime.datetime.strptime() wenn du so vorgehen möchtest.
Danke fürs Antworten, aber sehr hilfreich ist das nicht.
datetime.datetime.strptime() habe ich wohl gelesen, Ausführungsbeispiele in diesem konkreten Fall gibt es nicht.
Ein erster Versuch mit

Code: Alles auswählen

log_start_time = datetime.strptime(log_start_time_str, '%H:%M:%S')
wurde abgelehnt: AttributeError: module 'datetime' has no attribute 'strptime'

Code: Alles auswählen

log_start_time = time.strptime(log_start_time_str, '%H:%M:%S')
wurde angenommen..
Dass dieses nackte Aufrfufen von strftime nicht funktioniert, ist dir klar?
Natürlich ist mir klar, dass es nicht funktioniert, sonst würde ich hier nicht genau danach fragen.
Hilfreicher wäre eine Antwort gewesen, wie es gemacht werden soll.
Zuletzt geändert von RIN67630 am Sonntag 15. März 2020, 08:17, insgesamt 1-mal geändert.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Was heißt denn "wurde abgelehnt"?
Hilfreicher wäre eine Fehlermeldung.

Edit: Und ein vollständiger, ausführbarer Code (bis zur Fehlermeldung).
Zuletzt geändert von sparrow am Sonntag 15. März 2020, 08:20, insgesamt 1-mal geändert.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

sparrow hat geschrieben: Sonntag 15. März 2020, 08:15 Was heißt denn "wurde abgelehnt"?
Hilfreicer wäre eine Fehlermeldung.
Sorry habe es gerade gleichzeitig nachgepflegt:
AttributeError: module 'datetime' has no attribute 'strptime'

... und die Libraries wurden wie folgt am Anfang eingebunden:

Code: Alles auswählen

import time
import datetime
Zuletzt geändert von RIN67630 am Sonntag 15. März 2020, 08:23, insgesamt 1-mal geändert.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Wie sieht der komplette Code inkl. Importe aus?
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

Hier den relevanten Teil:

Code: Alles auswählen

#! /usr/bin/env python3

# getting libraries
import os
import subprocess
import time
import datetime

# source defaults
log_date_str = '20-03-10'             #logdate as string
log_start_time_str = '05:55:00'       #logstarttime as string


log_start_time = time.strptime(log_start_time_str, '%H:%M:%S')
log_end_time = log_start_time + datetime.timedelta(minutes = 6)
log_end_time_str = strftime('%H:%M:%S')
log_mid_time = log_start_time + datetime.timedelta(minutes = 3)
log_mid_time_str = strftime('%H:%M:%S')
Antwort:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/pi/delme.py", line 15, in <module>
    log_end_time = log_start_time + datetime.timedelta(minutes = 6)
TypeError: can only concatenate tuple (not "datetime.timedelta") to tuple
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Die gesuchte Funktion ist nicht datetime.strptime sondern datetime.datetime.strptime

Code: Alles auswählen

import datetime
>>> type(datetime)
<class 'module'>
>>> type(datetime.datetime)
<class 'type'>
>>> type(datetime.datetime.strptime)
<class 'builtin_function_or_method'>
In dem Modul "datetime" gibt es einen Klasse "datetime". Und die beinhaltet die Funktion, die du brauchst.
Dass Modulname und Klassenname in diesem Fall gleich sind, ist unglücklich. Die Klasse direkt in den Namensraum zu importieren überschreibt das Modul. Außerdem sind Modul- und Klassenname relativ lang. Deshalb ist das einer der wenigen Fälle, bei denen ich etwas unter anderem Namen in den Namensraum hole.

Code: Alles auswählen

import datetime
type(datetime.datetime.strptime)
<class 'builtin_function_or_method'>
oder

Code: Alles auswählen

from datetime import datetime as dt
type(dt.strptime)
<class 'builtin_function_or_method'>
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist sogar noch unglücklicher, weil die Klasse datetime sich nicht an die Nameskonvention für Klassen hält. dt ist als Klassenname zu kryptisch und falsch geschrieben.
Besser wäre

Code: Alles auswählen

from datetime import datetime as DateTime, timedelta as TimeDelta
Und dann

Code: Alles auswählen

log_start_time_str = input('Please enter log start time (hh:mm:ss):')
log_start_time = DateTime.strptime(log_start_time_str, '%H:%M:%S')
log_end_time = log_start_time + TimeDelta(minutes=6)
log_mid_time = log_start_time + TimeDelta(minutes=3)
print(f"log end time {log_end_time:%H:%M:%S}")
Konvertierung als String erst wenn man es braucht.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

Darf ich mal ausnahmsweise um ein funktionierendes Beispiel bitten?

Code: Alles auswählen

#! /usr/bin/env python3

# getting libraries
import os
import subprocess
import time
from datetime import datetime as dt
type(dt.strptime)
<class 'builtin_function_or_method'>

# source defaults
log_date_str = '20-03-10'             #logdate as string
log_start_time_str = '05:55:00'       #logstarttime as string


log_start_time = dt.strptime(log_start_time_str, '%H:%M:%S')
log_end_time = log_start_time + datetime.timedelta(minutes = 6)
log_end_time_str = strftime('%H:%M:%S')
log_mid_time = log_start_time + datetime.timedelta(minutes = 3)
log_mid_time_str = strftime('%H:%M:%S')
hier stolpert das schon beim Import:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/pi/delme.py", line 9
    <class 'builtin_function_or_method'>
    ^
SyntaxError: invalid syntax
Edit: falls es einen besseren Weg gibt, als datetime(), gern!
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Das waren Sitzungen im interktiven Interpreter, die dir zeigen sollten, was sich hinter den Namen verbirgt.
Ergo auch die entsprechenden Ausgaben. Die gehören nicht in den Code.

Code: Alles auswählen

#! /usr/bin/env python3

import os
import subprocess
import time
from datetime import datetime as DateTime

# source defaults
log_date_str = '20-03-10'             #logdate as string
log_start_time_str = '05:55:00'       #logstarttime as string

log_start_time = DateTime.strptime(log_start_time_str, '%H:%M:%S')
Dein Code solle von der Modulebene in Funktionen wandern.
Wenn log_date_str Konstanten sind, bleiben die auf der Modulebene, werde aber durch komplette Schreibung mit Großbuchstraben als Konstannten erkennbar.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

Sirius3 hat geschrieben: Sonntag 15. März 2020, 08:48 Besser wäre

Code: Alles auswählen

from datetime import datetime as DateTime, timedelta as TimeDelta
Und dann

Code: Alles auswählen

log_start_time_str = input('Please enter log start time (hh:mm:ss):')
log_start_time = DateTime.strptime(log_start_time_str, '%H:%M:%S')
log_end_time = log_start_time + TimeDelta(minutes=6)
log_mid_time = log_start_time + TimeDelta(minutes=3)
print(f"log end time {log_end_time:%H:%M:%S}")
Vielen Dank Sirius! ich kann endlich weitermachen!
8)
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

sparrow hat geschrieben: Sonntag 15. März 2020, 09:09 Das waren Sitzungen im interktiven Interpreter, die dir zeigen sollten, was sich hinter den Namen verbirgt.
Ergo auch die entsprechenden Ausgaben. Die gehören nicht in den Code.
Danke, halb verstanden.
ich bin noch auf dem Verkehrsübungsplatz, nicht auf dem Nürburgring.
Ich verstehe es wesentlich besser, wenn man das Narrativ eines Fahrschullehrers benutzt.

:D

...Und dazu noch, wenn man zuerst kaputte Libraries vor der Fahrbahn flicken muss, um überhaupt weiterfahren zu können...
:mrgreen:
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

sparrow hat geschrieben: Sonntag 15. März 2020, 09:09 ...
Wenn log_date_str Konstanten sind, bleiben die auf der Modulebene, werde aber durch komplette Schreibung mit Großbuchstraben als Konstannten erkennbar.
danke für den Hinweis, Sparrow, das werde ich für Konstanten machen, ich bin ja nicht lernresistent.

In diesem Fall ist es allerdings keine Konstante, sondern -wie es auch den Kommentar zuvor klarmacht-, lediglich Vorberlegungen, um dem Anwender die Dateneingabe zu erleichtern.
im echten Code werden die Daten vom Anwender überschrieben, ...oder auch nicht wenn er faul ist. :D
Wenn der Code mal funktioniert, habe ich vor dieser schiere Vorberlegung durch die defaults aus einer "persistance.dat" zu übernehmen...
Aber so weit bin ich noch nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Warum willst Du das eigentlich machen? Falls das als Anpassung von Zeitzonen sein soll ist das der falsche Ansatz. Da wäre es sinnvoller sich das `pytz`-Modul her zu nehmen und tatsächlich die Zeiten in eine andere Zeitzone umzurechnen, also inklusive den Sachen wie Sommer-/Winterzeit und ähnliches. Am besten fährt man bei so etwas wenn man UTC arbeitet und nur für die Anzeige und eventuell die Eingabe mit lokalen Zeitangaben arbeitet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

__blackjack__ hat geschrieben: Sonntag 15. März 2020, 17:44 Warum willst Du das eigentlich machen? Falls das als Anpassung von Zeitzonen sein soll ist das der falsche Ansatz.
Das ist es nicht. Zeitzonen sind erstmal irrelevant, ich bin hier völlig "naiv". :D und das ist gut so!

Es geht darum aus einer große Log Datei mit Timestamps (aber gegebenenfalls mit Lücken und Aussetzern) ein interessanter Bereich zum Ausplotten suchen.
Der Anwender gibt eine Zeit vor, die Mitte des gewünschten Plotbereichs sein soll, und das Programm soll die Grenzen des Plots in der Log-Datei suchen und hoffentlich (mindestens teilweise) finden.
Die Suche soll aus Zeitgründen als reiner Text erfolgen, man sollte in der Suchschleife möglichst wenig umrechnen/konvertieren müssen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

RIN67630 hat geschrieben: Sonntag 15. März 2020, 22:03 Das ist es nicht. Zeitzonen sind erstmal irrelevant, ich bin hier völlig "naiv". :D und das ist gut so!

Es geht darum aus einer große Log Datei mit Timestamps (aber gegebenenfalls mit Lücken und Aussetzern) ein interessanter Bereich zum Ausplotten suchen.
Da solltest du nicht unbedingt komplett naiv rangehen und alle Randfälle ignorieren. Zeitumstellungen existieren und können bei Logs, bzw. auch schon beim falschen Lesen von Logs, zu sehr spannenden und unsinnigen Ergebnissen führen.
Das Leben ist wie ein Tennisball.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

EyDu hat geschrieben: Montag 16. März 2020, 15:47 Da solltest du nicht unbedingt komplett naiv rangehen und alle Randfälle ignorieren. Zeitumstellungen existieren und können bei Logs, bzw. auch schon beim falschen Lesen von Logs, zu sehr spannenden und unsinnigen Ergebnissen führen.
Wenn wir erstmal nur die Sorge der Zeitumstellung zweimal im Jahr haben, dann wären wir froh...
Diese Zeitumstellung ist meistens kein Problem, die Menschen wissen das und nehmen auch in Kauf, dass gegebenenfalls eine große Lücke um 3:00 Uhr entsteht, oder, dass um diese Zeit gerade 1 h überschrieben wird.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Das nimmt man ja völlig unnötigerweise in Kauf, weil alle Daten als UTC abzuspeichern nicht wirklich Aufwand wäre.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

Sirius3 hat geschrieben: Montag 16. März 2020, 16:45 Das nimmt man ja völlig unnötigerweise in Kauf, weil alle Daten als UTC abzuspeichern nicht wirklich Aufwand wäre.
Das wird schon so seit 15 Jahren im Projekt gehandhabt und hat niemanden je gestört.
Jetzt alles auf dem Kopf zu stellen, würde die Mitglieder nur verunsichern.
Antworten