Given a string in a 24 hour format the program outputs a 12 hour format. The rules are:
- The output format must be 'hh:mm a.m.' if it represents before midday and 'hh:mm p.m.' after midday
- When the hour is less than 10:00 you should not write a 0 before the hour, example: '9:05 a.m.'
For example:
12:30 → 12:30 p.m.
09:00 → 9:00 a.m.
23:15 → 11:15 p.m.
The code:
import datetime
def time_converter(time):
midday_dt = datetime.datetime.strptime('12:00','%H:%M')
time_dt = datetime.datetime.strptime(time, '%H:%M')
if time_dt >= midday_dt:
if time_dt >= datetime.datetime.strptime('13:00','%H:%M'):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes}'
time += ' p.m.'
else:
if time_dt < datetime.datetime.strptime('10:00','%H:%M'):
time = time[1:]
if is_midnight(time_dt):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes:02d}'
time += ' a.m.'
return time
def clamp_to_twelve(time_dt, midday_dt):
clamp_dt = time_dt - midday_dt
minutes, seconds = divmod(clamp_dt.seconds, 60)
hours, minutes = divmod(minutes, 60)
return [hours, minutes]
def is_midnight(time_dt):
return (time_dt >= datetime.datetime.strptime('00:00','%H:%M') and
time_dt <= datetime.datetime.strptime('00:59','%H:%M'))
if __name__ == '__main__':
assert time_converter('12:30') == '12:30 p.m.'
assert time_converter('09:00') == '9:00 a.m.'
assert time_converter('23:15') == '11:15 p.m.'
1 Answer 1
To help with readability, I'd just import datetime.datetime
and then alias it, that way you aren't typing datetime.datetime
all over the place:
from datetime import datetime as dt
def time_converter(time):
midday_dt = dt.strptime('12:00','%H:%M')
time_dt = dt.strptime(time, '%H:%M')
if time_dt >= midday_dt:
if time_dt >= dt.strptime('13:00','%H:%M'):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes}'
time += ' p.m.'
else:
if time_dt < dt.strptime('10:00','%H:%M'):
time = time[1:]
if is_midnight(time_dt):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes:02d}'
time += ' a.m.'
return time
def clamp_to_twelve(time_dt, midday_dt):
clamp_dt = time_dt - midday_dt
minutes, seconds = divmod(clamp_dt.seconds, 60)
hours, minutes = divmod(minutes, 60)
return [hours, minutes]
def is_midnight(time_dt):
return (time_dt >= dt.strptime('00:00','%H:%M') and
time_dt <= dt.strptime('00:59','%H:%M'))
if __name__ == '__main__':
assert time_converter('12:30') == '12:30 p.m.'
assert time_converter('09:00') == '9:00 a.m.'
assert time_converter('23:15') == '11:15 p.m.'
Next, if you are just unpacking the list
returned from clamp_to_twelve
, I would just return a tuple
:
def clamp_to_twelve(time_dt, midday_dt):
clamp_dt = time_dt - midday_dt
minutes, seconds = divmod(clamp_dt.seconds, 60)
hours, minutes = divmod(minutes, 60)
return hours, minutes
This saves you from having to construct the list, as well as the additional overhead of over-allocating memory to take into account the mutable list
.
As a last optimization, you could refactor your if
statements to not be nested. Because you are using if if
rather than if elif
, all of your statements are executed within the nested blocks:
def time_converter(time):
midday_dt = dt.strptime('12:00','%H:%M')
time_dt = dt.strptime(time, '%H:%M')
if time_dt >= dt.strptime('13:00', '%H:%M'):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes} p.m.'
elif time_dt > midday_dt:
time += ' p.m.'
elif time_dt < dt.strptime('10:00', '%H:%M'):
time = f'{time[1:]} a.m.'
elif is_midnight(time_dt):
hours, minutes = clamp_to_twelve(time_dt, midday_dt)
time = f'{hours}:{minutes} a.m.'
else:
time += ' a.m.'
return time
The only issue being that the order is quite important, since time_dt > midday_dt
and time_dt >= dt.strptime('13:00', '%H:%M')
are not mutually exclusive. However, you do get a slight time bump because of the separation of blocks of code:
python -m timeit -s "from file import time_converter, time_converter_2; times = ['12:30', '09:00', '11:15']" '(time_converter(t) for t in times)'
1000000 loops, best of 3: 0.275 usec per loop
python -m timeit -s "from file import time_converter, time_converter_2; times = ['12:30', '09:00', '11:15']" '(time_converter_2(t) for t in times)'
1000000 loops, best of 3: 0.277 usec per loop
Emphasis on slight. Depends on what you find more readable.
Explore related questions
See similar questions with these tags.