I have exported some data from another programm, where I added up time for a station waiting. So after some time, I have the format '32:00:00:33.7317' for the waiting time.
This is my function to convert every date into the format I want:
def Datum_formatieren(Datensatz):
if len(str(Datensatz)) == 24:
return datetime.datetime.strptime(Datensatz, "%d.%m.%Y %H:%M:%S.%f").strftime("%d%H%M")
elif len(str(Datensatz)) == 3:
return 0
#return datetime.datetime.strptime(Datensatz, "%S.%f").strftime("%d%H%M")
elif len(str(Datensatz)) == 5:
return str(Datensatz)
elif len(str(Datensatz)) == 7:
return str(Datensatz)
elif len(str(Datensatz)) == 6:
return datetime.datetime.strptime(str(Datensatz), "%S.%f").strftime("%d%H%M")
elif len(str(Datensatz)) == 9 or len(str(Datensatz))==10:
return datetime.datetime.strptime(str(Datensatz), "%M:%S.%f").strftime("%d%H%M")
elif len(str(Datensatz)) == 12 or len(str(Datensatz)) ==13:
return datetime.datetime.strptime(str(Datensatz), "%H:%M:%S.%f").strftime("%d%H%M")
elif len(str(Datensatz)) == 15 or len(str(Datensatz)) == 16:
return datetime.datetime.strptime(str(Datensatz), "%d:%H:%M:%S.%f").strftime("%d%H%M")
I get the following error since python does not recognize days above 30 or 31:
ValueError: time data '32:00:00:33.7317' does not match format '%d:%H:%M:%S.%f'
How do I convert all entries with days above 31 into a format, which python can recognize?
CodePudding user response:
You are misusing datetime wich only map to correct dates with times - not "any amount time passed".
Use a timedelta
instead:
Adapted from datetime.timedelta:
from datetime import datetime, timedelta delta = timedelta( days=50, seconds=27, microseconds=10, milliseconds=29000, minutes=5, hours=8, weeks=2 ) print(datetime.now() delta)
You can add any timedelta to a normal datetime and get the resulting value.
If you want to stick wich your approach you may want to shorten it:
if len(str(Datensatz)) == 9 or len(str(Datensatz))==10:
if len(Datensatz) in (9,10):
Related: How to construct a timedelta object from a simple string (look at its answers and take inspiration with attribution from it)
CodePudding user response:
You're taking the
Datensatz
variable, converting it to string usingstr()
, then parsing it back into an internal representation; there is almost always a better way to do it.Can you check what type the
Datensatz
variable has, perhapsprint(type(Datensatz))
or based on the rest of your code?Most likely the
Datensatz
variable already has fields for the number of days, hours, minutes and seconds. It's usually much better to base your logic on those directly, rather than converting to string and back.As others have pointed out, you're trying to use a
datetime.datetime
to represent a time interval; this is incorrect. Instead, you need to either:Use the
datetime.timedelta
type, which is designed for time intervals. It can handle periods over 30 days correctly:>>> print(datetime.timedelta(days=32, seconds=12345)) 32 days, 3:25:45 >>>
Since your function is named
Datum_formatieren
, perhaps you intend to takeDatensatz
and convert it to string, for output to the user or to another system.In that case, you should take the fields directly in
Datensatz
and convert them appropriately, perhaps using f-strings or % formatting. Depending on the situation, you may need to do some arithmetic. The details will depend on the type ofDatensatz
and the format you need on the output.
CodePudding user response:
You cannot use datetime.datetime.strptime()
to construct datetimes that are invalid - why see other answer.
You can however leverage datetime.timespan
:
import datetime
def Datum_formatieren(Datensatz):
# other cases omitted for brevity
# Input: "days:hours:minutes:seconds.ms"
if len(Datensatz) in (15,16):
k = list(map(float,Datensatz.split(":")))
secs = k[0]*60*60*24 k[1]*60*60 k[2]*60 k[3]
td = datetime.timedelta(seconds=secs)
days = td.total_seconds() / 24 / 60 // 60
hours = (td.total_seconds() - days * 24*60*60) / 60 // 60
minuts = (td.total_seconds() - days *24*60*60 - hours * 60*60) // 60
print(td)
return f"{td.days}{int(hours):02d}{int(minuts):02d}"
print(Datum_formatieren("32:32:74:33.731"))
Output for "32:32:74:33.731"
:
33 days, 9:14:33.731000 # timespan
330914 # manually parsed