How could I implement “HH:MM:SS” format - python

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}')

Related

Python convert string to datetime but formatting is not very predictable

I'm extract the execution time of a Linux process using Subprocess and ps. I'd like to put it in a datetime object, to perform datetime arithmetic. However, I'm a little concerned about the output ps returns for the execution time:
1-01:12:23 // 1 day, 1 hour, 12 minutes, 23 seconds
05:39:03 // 5 hours, 39 minutes, 3 seconds
15:06 // 15 minutes, 6 seconds
Notice there is no zero padding before the day. And it doesn't include months/years, whereas technically something could run for that long.
Consequently i'm unsure what format string to convert it to a timedelta because I don't want it to break if a process has ran for months, or another has only ran for hours.
UPDATE
Mozway has given a very smart answer. However, I'm taking a step back and wondering if I can get the execution time another way. I'm currently using ps to get the time, but it means I also have the pid. Is there something else I can do with the pid, to get the execution time in a simpler format?
(Can only use official Python libraries)
UPDATE2
It's actually colons between the hours, mins and seconds.
You should use a timedelta
Here is a suggestion on how to convert from your string:
import datetime
s = '1-01-12-23'
out = datetime.timedelta(**dict(zip(['days', 'hours', 'minutes', 'seconds'],
map(int, s.split('-')))))
Output:
datetime.timedelta(days=1, seconds=4343)
If you can have more or less units, and assuming the smallest units are present you take advantage of the fact that zip stops with the smallest iterable, just reverse the inputs:
s = '12-23'
units = ['days', 'hours', 'minutes', 'seconds']
out = datetime.timedelta(**dict(zip(reversed(units),
map(int, reversed(s.split('-'))))))
Output:
datetime.timedelta(seconds=743)
As a function
Using re.split to handle the 1-01:23:45 format
import re
def to_timedelta(s):
units = ['days', 'hours', 'minutes', 'seconds']
return datetime.timedelta(**dict(zip(reversed(units),
map(int, reversed(re.split('[-:]', s))))))
to_timedelta('1-01:12:23')
# datetime.timedelta(days=1, seconds=4343)
to_timedelta('05:39:03')
# datetime.timedelta(seconds=20343)
to_timedelta('15:06')
# datetime.timedelta(seconds=906)

I want to get the output in the form of HH:MM:SS, so for example get 5 seconds to be expressed as 05 seconds? Python

Ive written this code and ive obtained the desired output however it is not in the correct format. Essentially the codewars challenge was to take a number of seconds up to around 350000 and then split it into hours then minutes then seconds. For example my code would take x seconds then express it as y:z:p (where y, z and p represent single digit integers) however i would like my code to express it as 0y:0z:0p unless y,z or p are already two digit integers.
Here is my code:
secs = 350000
mins = secs/60
hrs = mins/60
hrs_hol = int(hrs)
print(hrs_hol, hrs)
hrs_rem = hrs-hrs_hol
print(hrs_rem)
mins_from_hrs_rem = hrs_rem*60
mins_hol = int(mins_from_hrs_rem)
mins_rem = mins_from_hrs_rem - mins_hol
secs_from_min_rem = mins_rem*60
secs_final = int(secs_from_min_rem)
H = str(hrs_hol)
M = str(mins_hol)
S = str(secs_final)
print(H+':'+M+':'+S)
Thankyou!
Try this:
H = str(hrs_hol).zfill(2)
M = str(mins_hol).zfill(2)
S = str(secs_final).zfill(2)
Remove the assignments to H, M & S then:
print(f'{hrs_hol:02d}:{mins_hol:02d}:{secs_final:02d}')
Here we use an f-string and a format specifier that indicates a minimum of two digits (left-padded with zero if necessary)

Convert integer to hours and minutes

I'm working on a Python script that will read a file and grab a string total_time. Currently, this is what I have.
if("Total time" in data):
total_time=int(filter(str.isdigit, data))
print(total_time)
Output: 419
I'm trying to find the best way to read lots of files, grab this total time, and convert 419 into 4 hours and 19 minutes to allow me to do some statics and analytics with this.
Passing format argument to datetime in Pandas:
t="419"
a = pd.to_datetime(t, format='%H%M')
print(a.hour)
print(a.minute)
The built-in function divmod() seems appropriate here!
>>> a = 5
>>> b = 3
>>> divmod(a,b) # (a // b, a % b)
(1,2)
For your specific situation:
def dataToTime(data):
''' Returns a list of (hour, minute) tuples from
a list of strings '''
total_times = filter(str.isdigit,data)
return [divmod(int(time),100) for time in total_times]
If you would like to parse the data as you are inputting it try the re module which has the method re.sub() for regex substitution
>>> import re
>>> s = '| Total time | 4:19 | | |--------------+--------+------| –'
>>> h = int(re.sub(r':.*$|[^0-9]','',s))
>>> m = int(re.sub(r'^.*:|[^0-9]','',s))
>>> print h,m
(4,19)
Given some string set as
s = '419'
you can get the upper and lower digits by converting to an integer, then using modulo and integer division. The integer conversion can be encapsulated in a try-except block catching ValueError if you have a reasonable response to invalid inputs:
n = int(s)
hours = n // 100 # Truncating integer division
minutes = n % 100 # Modulo removes the upper digits

Keeping a strange time format, and adding values to it in python

So i have been trying to add a time format to my REST calls in python, but there seems to always be some type of issue, first of all here is the time format requirement, and it has to be exact, or it wont work unfortunately.
Use the following ISO-8601 compliant date/time format in request parameters.
yyyy-MM-dd'T'HH:mm:ss.SSSXXX
For example, May 26 2014 at 21:49:46 PM could have a format like one of the following:
l In PDT: 2014-05-26T21:49:46.000-07:00
l In UTC: 2014-05-26T21:49:46.000Z
Code Description
yyyy Four digit year
MM Two-digit month (01=January, etc.)
dd Two-digit day of month (01 through 31)
T Separator for date/time
HH Two digits of hour (00 through 23) (am/pm NOT allowed)
mm Two digits of minute (00 through 59)
ss Two digits of second (00 through 59)
SSS Three digit milliseconds of the second
XXX ISO 8601 time zone (Z or +hh:mm or -hh:mm)
So, what i have tried before is:
def format_time(self, isnow):
currentdt = datetime.datetime.utcnow()
if not isnow:
currentdt += datetime.timedelta(0,3)
(dt, micro) = currentdt.strftime('%Y-%m-%dT%H:%M:%S.%f').split('.')
dt = "%s.%03dZ" % (dt, int(micro) / 1000)
return dt
Now, this might return it in the kinda right format, but there is still the problem with timezones.
The end result i am trying to accomplish, is when i execute this, it finds the current time, (Amsterdam timezone/GMT/UTC+1), and creates it in this format.
And the else statement, to get the same time, but append X seconds.
Would anyone be so kind to help me out here?
Ok, so you got the microseconds formatted as milliseconds, well done there.
Now your challenge is to handle the timezone offset; it can't only be Z.
And to make things more difficult, strftime's %z format gives + (or -) HHMM, instead of HH:MM.
So you'll need to deal with that. Here's one way to do it:
Python 3:
def format_time(self, isnow):
currentdt = datetime.datetime.now(datetime.timezone.utc)
if not isnow:
currentdt += datetime.timedelta(0,3)
(dt, micro) = currentdt.strftime('%Y-%m-%dT%H:%M:%S.%f').split('.')
tz_offset = currentdt.astimezone().strftime('%z')
tz_offset = "Z" if tz_offset == "" else tz_offset[:3] + ":" + tz_offset[3:]
dt = "%s.%03d%s" % (dt, int(micro) / 1000, tz_offset)
return dt
Python 2:
import pytz
from dateutil.tz import *
def format_time(self, isnow):
currentdt = datetime.datetime.now(pytz.utc)
if not isnow:
currentdt += datetime.timedelta(0,3)
(dt, micro) = currentdt.strftime('%Y-%m-%dT%H:%M:%S.%f').split('.')
tz_offset = currentdt.astimezone(tzlocal()).strftime('%z')
tz_offset = "Z" if tz_offset == "" else tz_offset[:3] + ":" + tz_offset[3:]
dt = "%s.%03d%s" % (dt, int(micro) / 1000, tz_offset)
return dt
Response to comment:
I needed to make a few changes. It's remarkably non-trivial to find the current timezone. The easiest way I could find was from https://stackoverflow.com/a/25887393/1404311 and I've integrated those concepts into the code that is now above.
Basically, instead of utcnow(), you should use now(datetime.timezone.utc). The former gives a naive datetime, while the latter gives a datetime set to UTC, but aware that it is. Then use astimezone() to make it aware of your local timezone, then use strftime('%z') to get the time offzone from there. THEN go through the string manipulation.

Need help converting total number of minutes into hour and minute format

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.

Categories