I am running a daily report and I'd like to keep a log of how long it takes to run each day.
I get a report_time timedelta object by calling datetime.datetime.now() at beginning and end and then getting the difference between the two values.
I have a text file that has two lines. Line 1 is today's run-time. Line 2 is total cumulative run time.
The issue is that when I try to parse Line 2 into a datetime.datetime object (to then create a timedelta object to add today's report time) it won't let me do so if the cumulative run time is over 24 hours (I guess because it no longer makes a valid date.
Any idea how to get around this (essentially parse a string into a time.delta object when it won't conform to a datetime.datetime format?
Code:
report_stats = f.read()
today_cumulative_reports_time = report_stats.splitlines()[0]
prev_total_reports_time = report_stats.splitlines()[1]
today_cumulative_reports_time = datetime.datetime.strptime(today_cumulative_reports_time,
'%H:%M:%S.%f')
today_cumulative_reports_time = datetime.timedelta(hours=today_cumulative_reports_time.hour,
minutes=today_cumulative_reports_time.minute,
seconds=today_cumulative_reports_time.second,
microseconds=today_cumulative_reports_time.microsecond)
prev_total_reports_time = datetime.datetime.strptime(prev_total_reports_time, '%H:%M:%S.%f')
prev_total_reports_time = datetime.timedelta(hours=prev_total_reports_time.hour,
minutes=prev_total_reports_time.minute,
seconds=prev_total_reports_time.second,
microseconds=prev_total_reports_time.microsecond)
cumulative_run_time = report_time + today_cumulative_reports_time + prev_total_reports_time
f.close()
Error:
ValueError: time data '24:54:03.294820' does not match format '%H:%M:%S.%f'
Manually parse the string and then construct the timedelta object:
from datetime import timedelta
time_string = '24:54:03.294820'
hours, minutes, seconds = map(float, time_string.split(':'))
t_delta = timedelta(hours=hours, minutes=minutes, seconds=seconds)
print(t_delta)
outputs
1 day, 0:54:03.294820
Related
I get the departure variable by asking for it as input into a string. Using this code as shortened version to show where it starts.
departure = "2022-11-12 14:30"
datetime_object = datetime.strptime(departure, "%Y-%m-%d %H:%M")
current_time = datetime.utcnow()
print(datetime_object-timedelta(current_time))
I am trying to subtract this and basically receive any sort of outcome in days + mins +seconds or in just one variable like minutes. i.e.
>>>
10000 mins
What I am currently getting is this
>>>
print(datetime_object-timedelta(current_time))
TypeError: unsupported type for timedelta days component: datetime.datetime
I am using datetime.strptime() to convert a string containing time and date from a sensor into a datetime object.
The code sometimes fails. Minimal example:
datetime.strptime('1/9/2021 24:01:53', '%d/%m/%Y %H:%M:%S')
Output error:
ValueError: time data '1/9/2021 24:01:53' does not match format '%d/%m/%Y %H:%M:%S'
I am guessing this has to do with the fact that the time is more than 23:59:59 - which seems to me a non-realistic time (I would think that 1/9/2021 24:01:53 could potentially be 2/9/2021 00:01:53 - a time format which I have never seen).
Is this a non-standard way of representing time or possibly a hardware/software issue with the sensor acquisition system? If it is a different way of representing time, how can I convert it to a standard datetime object?
Kind regards,
D.F.
If the hour exceeds 23 in a variable representing time, a good option is to create a timedelta from it, which you can then add to a datetime object. For given example that might look like
from datetime import datetime, timedelta
def custom_todatetime(s):
"""
split date/time string formatted as 'DD/MM/YYYY hh:mm:ss' into date and time parts.
parse date part to datetime and add time part as timedelta.
"""
parts = s.split(' ')
seconds = sum(int(x) * 60 ** i for i, x in enumerate(reversed(parts[1].split(':'))))
return datetime.strptime(parts[0], "%d/%m/%Y") + timedelta(seconds=seconds)
s = '1/9/2021 24:01:53'
print(custom_todatetime(s))
# 2021-09-02 00:01:53
Note: conversion of hh:mm:ss to seconds taken from here - give a +1 there if helpful.
I want to add hours to a datetime and use:
date = date_object + datetime.timedelta(hours=6)
Now I want to add a time:
time='-7:00' (string) plus 4 hours.
I tried hours=time+4 but this doesn't work. I think I have to int the string like int(time) but this doesn't work either.
Better you parse your time like below and access datetime attributes for getting time components from the parsed datetime object
input_time = datetime.strptime(yourtimestring,'yourtimeformat')
input_seconds = input_time.second # for seconds
input_minutes = input_time.minute # for minutes
input_hours = input_time.hour # for hours
# Usage: input_time = datetime.strptime("07:00","%M:%S")
Rest you have datetime.timedelta method to compose the duration.
new_time = initial_datetime + datetime.timedelta(hours=input_hours,minutes=input_minutes,seconds=input_seconds)
See docs strptime
and datetime format
You need to convert to a datetime object in order to add timedelta to your current time, then return it back to just the time portion.
Using date.today() just uses the arbitrary current date and sets the time to the time you supply. This allows you to add over days and reset the clock to 00:00.
dt.time() prints out the result you were looking for.
from datetime import date, datetime, time, timedelta
dt = datetime.combine(date.today(), time(7, 00)) + timedelta(hours=4)
print dt.time()
Edit:
To get from a string time='7:00' to what you could split on the colon and then reference each.
this_time = this_time.split(':') # make it a list split at :
this_hour = this_time[0]
this_min = this_time[1]
Edit 2:
To put it all back together then:
from datetime import date, datetime, time, timedelta
this_time = '7:00'
this_time = this_time.split(':') # make it a list split at :
this_hour = int(this_time[0])
this_min = int(this_time[1])
dt = datetime.combine(date.today(), time(this_hour, this_min)) + timedelta(hours=4)
print dt.time()
If you already have a full date to use, as mentioned in the comments, you should convert it to a datetime using strptime. I think another answer walks through how to use it so I'm not going to put an example.
I am trying to write a countdown clock script. I want to use a set date in the future and have it count down in a nice readable format. Hours, Min, Sec. I am going to print to a 16x2 lCD display. The problem I'm having is trying to take the output of the difference between dates into a nice format. I have attached what I have so far. I receive the error:
AttributeError: 'datetime.timedelta' object has no attribute 'strftime'
This is my code:
from datetime import datetime
from time import strftime
deploy = datetime(2015, 3, 21, 0, 0)
mydate = datetime.now() - deploy
print (mydate.strftime("%b %d %H:%M:%S"))
I know how to print to my LCD and create a loop, just need help with this part.
There are two issues:
the time difference may be incorrect if you use local time represented as a naive datetime object if the corresponding local times have different utc offsets e.g., around a DST transition
the difference is timedelta object that has no strftime() method
To fix it, convert deploy from local timezone to UTC:
#!/usr/bin/env python
import time
from datetime import datetime, timedelta
deploy = datetime(2015, 3, 21, 0, 0) # assume local time
timestamp = time.mktime(deploy.timetuple()) # may fail, see the link below
deploy_utc = datetime.utcfromtimestamp(timestamp)
elapsed = deploy_utc - datetime.utcnow() # `deploy` is in the future
where elapsed is the elapsed time not counting leap seconds (such as 2015-07-01 00:59:60 BST+0100).
More details on when time.mktime() may fail see at Find if 24 hrs have passed between datetimes - Python.
To convert timedelta to string, you could use str() function:
print(elapsed) # print full timedelta
# remove microseconds
trunc_micros = timedelta(days=elapsed.days, seconds=elapsed.seconds)
print(trunc_micros) # -> 20 days, 13:44:14 <- 17 chars
# remove comma
print(str(trunc_micros).replace(',', ''))
# -> 20 days 13:44:14 <- 16 chars
If you want a different format then convert to hours, minutes, second using divmod() function:
seconds = elapsed.days*86400 + elapsed.seconds # drop microseconds
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
print("{hours:02d}:{minutes:02d}:{seconds:02d}".format(**vars()))
# -> 493:44:14
I'm dealing with a large amount of data that has both values and times (in strings). I am converting the string time values into datetime values with the following code:
time = datetime.datetime.strptime(time, " %H:%M:%S.%f")
The only problem is that some of my data has the format: 24:00:00.004. So some of the data is actually over 24 hours
Python is giving me this error:
ValueError: time data ' 24:00:00:004' does not match format ' %H:%M:%S.%f'
The %H parameter can only parse values in the range 0-23. You'll have to manually deal with those specific time stamps:
try:
time = datetime.datetime.strptime(time, " %H:%M:%S.%f")
except ValueError:
time = time.replace(' 24', ' 23')
time = datetime.datetime.strptime(time, " %H:%M:%S.%f")
time += datetime.timedelta(hours=1)
Try parsing the hours separately:
hours, rest = time.split(':', 1)
time = datetime.timedelta(hours=int(hours)) + datetime.datetime.strptime(rest, "%M:%S.%f")
Seems like your data does not contain dates, but time spans, so you should maybe store your data as timedelta instead of datetime.
You can use this function to create a timedelta from your strings:
import re
from datetime import timedelta
def parseTimeDelta(s):
d = re.match(
r'((?P<days>\d+) days, )?(?P<hours>\d+):'
r'(?P<minutes>\d+):(?P<seconds>\d+)\.(?P<milliseconds>\d+)',
str(s)).groupdict(0)
return timedelta(**dict(( (key, int(value))
for key, value in d.items() )))
Parsing your time string '24:00:00.004' like this
>>>t = parseTimeDelta('24:00:00.04')
would result in a timedelta represented like this
>>> print t
1 day, 0:00:00.004000