I want to take the time that some operations need; so I wrote:
def get_formatted_delta(start_time):
seconds = ( datetime.datetime.now() - start_time ).total_seconds()
m, s = divmod(seconds, 60)
min = '{:02.0f}'.format(m)
sec = '{:02.4f}'.format(s)
return '{} minute(s) {} seconds'.format(min, sec)
but when I run that; I get printouts like:
00 minute(s) 1.0010 seconds
Meaning: as expected, 0 minutes are showing up as "00".
But 1 seconds shows up as 1.xxxx - instead of 01.xxxx
So, what is wrong with my format specification?
The field width applies to the whole field including the decimals and the decimal point. For 4 decimals plus the point, plus 2 places for the integer portion, you need 7 characters:
>>> format(1.001, '07.4f')
'01.0010'
You don't need to format those floats separately, you can do all formatting and interpolation in one step:
def get_formatted_delta(start_time):
seconds = ( datetime.datetime.now() - start_time ).total_seconds()
m, s = divmod(seconds, 60)
return '{:02.0f} minute(s) {:07.4f} seconds'.format(m, s)
Related
I am asked to do this:
Write a program that adds one second to a clock time, given its hours, minutes and seconds.
Input consists of three natural numbers h, m and s that represent a clock time, that is, such that h<24, m<60 and s<60.
This is the code I came up with:
from easyinput import read
h = read(int)
m = read(int)
s = read(int)
seconds = (s+1)%60
minutes = (m + (s+1)//60)%60
hours = h + (m + (s+1)//60))//60
print(hours, minutes, seconds)
It does its function well, if I have
13 59 59
it returns
14 0 0
I am sure it could be bettered, but that's not the problem right now.
The problem is that I need the format to be like this:
11:33:16
It should be “HH:MM:SS”, and I don't know how to do it.
Anyone could help me?? Thanksss :)))
Use an f-string with format modifiers. 02d says "an int with field width 2 padded with 0."
print(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
>>> hours = 13
>>> minutes = 3
>>> seconds = 5
>>> print(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
13:03:05
>>>
Note that the d in the format specifiers is unnecessary. You could write:
print(f"{hours:02}:{minutes:02}:{seconds:02}")
Documentation on f-strings.
Usually, you don't want to deal with calculating date and time yourself, so a better approach is to use the native library that works with date and time out of the box:
from datetime import datetime, timedelta
from easyinput import read
h, m, s = read(int), read(int), read(int)
time = datetime.now().replace(hour=h, minute=m, second=s)
time += timedelta(seconds=1)
print(time.strftime("%H:%M:%S"))
print(f'{hours:>02}:{minutes:>02}:{seconds:>02}')
Running this
import time
import datetime
timenow = time.time()
timedifference = time.time() - timenow
timedifference = datetime.timedelta( seconds=timedifference )
print( "%s" % timedifference )
I got this:
0:00:00.000004
How can I format trimming the microseconds to 2 decimal digits using the deltatime object?
0:00:00.00
Related questions:
Timedelta in hours,minutes,seconds,microseconds format
Formatting microseconds to two decimal places (in fact converting microseconds into tens of microseconds)
Convert the timedifference to a string with str(), then separate on either side of the decimal place with .split('.'). Then keep the first portion before the decimal place with [0]:
Your example with the only difference on the last line:
import time
import datetime
timenow = time.time()
timedifference = time.time() - timenow
timedifference = datetime.timedelta( seconds=timedifference )
print( "%s" % str(timedifference).split('.')[0] )
generates:
0:00:00
Another solution is to split the fractional part numerically and format it separately:
>>> seconds = 123.995
>>> isec, fsec = divmod(round(seconds*100), 100)
>>> "{}.{:02.0f}".format(timedelta(seconds=isec), fsec)
'0:02:04.00'
As you can see, this takes care of the rounding. It is also easy to adjust the output precision by changing 100 above to another power of 10 (and adjusting the format string):
def format_td(seconds, digits=2):
isec, fsec = divmod(round(seconds*10**digits), 10**digits)
return ("{}.{:0%d.0f}" % digits).format(timedelta(seconds=isec), fsec)
You'll have to format it yourself. A timedelta object contains days, seconds and microseconds so you'll have to do the math to convert to days/hours/min/sec/microsec and then format using python string.format. For your microsec, you'll want ((microsec+5000)/10000) to get the top two digits (the +5000 is for rounding).
A bit late, but here's a 2021 answer with f-strings (modified from #Seb's original answer):
def format_td(seconds, digits=3):
isec, fsec = divmod(round(seconds*10**digits), 10**digits)
return f'{timedelta(seconds=isec)}.{fsec:0{digits}.0f}'
I have a TimeField() in my django models. I want to convert the sum of the record of this to hours.
Here's the actual code in my view:
hours_week_decimal = Timesheet.objects.filter(owner = request.user.pk, week = datetime.datetime.now().isocalendar()[1]).aggregate(total=Sum('working_hour')) # this method return a dict of decimal
total_hours_week = convertDecimalToHours(hours_week_decimal)
and the related function:
def convertDecimalToHours(times):
total_time = 0
for k, v in times.items():
total_time += int(v)
print("type: {} - value: {}".format(type(total_time), total_time))
This returned me:
type: int - value: 166000
I have two hours:
Monday (08:30) and Tuesday(08:30)
It must have returned me "17:00"
Hope you can help me in solving this problem :)
The problem is that 30m+30m = 60m that yes, is 1h, but you expected that the calculator was able to understand that you want 30+30 = 1h
So, in your case, you have to explicit convert 8:30 to 8.5
A fast but not graceful approach to extend your example with few lines can be:
Convert your ints to strings.
Cut out the hours (positions 0 and 1) and multiply for 60 to obtain minutes.
Sum this result to the minutes (positions 2 and 3)
After doing this for every TimeField you have, sum all your times converted in minutes and then reconvert in hours.
In your example:
def convertDecimalToHours(times):
total_time = 0
for k, v in times.items():
tmp_time = str(int(v))
minutes = int(tmp_time[2:4]) + int(tmp_time[0:2])*60
total_time += minutes / 60 # Now your 8:30 is 8.5
print("type: {} - value: {}".format(type(total_time), total_time))
Your output here will be 17.
I suggest you to use this as example to understand the concept, not as a packed solution to your problem.
thanks for your answer,
In my database, i have a column of type "Time". The value's stored like this: 08:30:00.000000.
with my previous code, the times variables (passed in parameters) are like that:
{'total': Decimal('166000.000000')}
I need help converting this into an hour and minute format using the remainder operator. I'm relatively new to python and coding in general, so help is greatly appreciated.
#Define the value of our variables
numberOfEpisodes = 13
minutesPerEpisode = 42
#Calculate the results
totalMinutes = numberOfEpisodes * minutesPerEpisode
equivalency=totalMinutes//minutesPerHour
#Display the output
print(numberOfEpisodes, 'episodes will take', totalMinutes, 'minutes to watch.') print('This is equivalent to', equivalency)
This is what I currently have, I am able to obtain the amount of hours there are, but I can't figure out how to adjust the code to include the remaining minutes.
Sorry if I don't make a whole lot of sense, but hopefully you'll understand.
You can use // integer division and % modulus for remainder. (You can read more about Python's int and float division here)
>>> numberOfEpisodes = 13
>>> minutesPerEpisode = 42
>>> totalMinutes = numberOfEpisodes * minutesPerEpisode
>>> totalMinutes
546
>>> minutesPerHour = 60
>>> totalHours = totalMinutes // minutesPerHour
>>> totalHours
9
>>> remainingMinutes = totalMinutes % minutesPerHour
>>> remainingMinutes
6
Result
>>> print('{} episodes will take {}h {}m to watch.'.format(numberOfEpisodes,totalHours, remainingMinutes))
13 episodes will take 9h 6m to watch.
Use the modulo operator %
#Define the value of our variables
numberOfEpisodes = 13
minutesPerEpisode = 42
#Calculate the results
totalMinutes = numberOfEpisodes * minutesPerEpisode
equivalency=totalMinutes//60
minutes= totalMinutes%60
#Display the output
print(numberOfEpisodes, 'episodes will take', totalMinutes, 'minutes to watch.')
print('This is equivalent to', equivalency,minutes)
Check out the timedelta documentation in the datetime module documents. You can create the durations as time deltas in minutes, and then when you want to display it you can ask timedelta to give it in whatever format you want. You could use arithmetic calculations to get the hours and minutes, but if you then need to use this data to calculate dates and times, for example to know at what time the show will be over if it starts at 09:00, you will have many extra steps to go through, instead of just using the timedelta.
I have a function, getHoursSince():
def getHoursSince (date):
prior = datetime.datetime.now() - datetime.timedelta(days=date)
priorHour = prior.hour
hoursSinceDate = ...
return hoursSinceDate
so, I can get a date object, given a constant value, i.e. if yesterday = 1, I can call getHoursSince(yesterday). What I don't know how to do is to get the number of hours between datetime.datetime.now() and the priorHour variable -- any ideas?
You are going about it the wrong way; you just convert the timedelta() to hours:
def getHoursSince(date):
return int(datetime.timedelta(days=date).total_seconds() // 3600)
which gives:
>>> getHoursSince(1)
24
>>> getHoursSince(1.5)
36
>>> getHoursSince(2)
48
>>> getHoursSince(3)
72
but you can just as well base that off of simple arithmetic:
def getHoursSince(date):
return int(24 * date)
The timedelta.total_seconds() documentation says:
For interval units other than seconds, use the division form directly
(e.g. td / timedelta(microseconds=1)).
Here's what that would look like in this case:
def getHoursSince(date):
return datetime.timedelta(days=date) // datetime.timedelta(hours=1)