Reputation: 20884
I have this magical incantation that I use (and understand) to populate a time field with the all hours of the day in fifteen minute intervals.
['%s:%s%s' % (h, m, ap) for ap in ('am', 'pm') for h in ([12] + range(1,12)) for m in ('00', '15','30','45')]
This prints out a list:
['12:00am', '12:15am', '12:30am', '12:45am', '1:00am',...
I am attempting to adjust that code so that it works for a start time and end time. For example I want it to start at 9am and end at 5pm.
When the time comes back from the database it is a time
object: datetime.time(18, 0)
What I tried to do was to take the hour
of the datetime.time
and start the range there. But my mind got kind of blown by the idea of adjusting it for am and pm.
How do I adjust the code to work with a start and end time?
Upvotes: 1
Views: 311
Reputation: 32429
You can do something like this. Write your own generator which works like range
and takes a time-object (which comes from your DB if I understand you correctly) as start and stop (exclusively):
#! /usr/bin/python3
import datetime
def timerange(start, stop, step = datetime.timedelta(minutes = 15)):
t = datetime.datetime(2000, 1, 1, start.hour, start.minute)
stop = datetime.datetime(2000, 1, 1 if start <= stop else 2, stop.hour, stop.minute)
while t < stop:
yield t.time()
t += step
Now you can use it like this and it yields time-objects:
nineam = datetime.time(9, 0) #from DB
fivepm = datetime.time(17, 0) #from DB
for t in timerange(nineam, fivepm):
print(t)
If you want it formatted, write another generator that returns a string according to your necessities:
def ftimerange(start, stop, step = datetime.timedelta(minutes = 15)):
for t in timerange(start, stop, step):
yield t.strftime('%I:%M%p')
for s in ftimerange(nineam, fivepm):
print(s)
This also works if start is before midnight and stop after it.
Here a working sample:
>>> elevenpm = datetime.time(23, 0)
>>> oneam = datetime.time(1, 0)
>>> for s in ftimerange(elevenpm, oneam): print(s)
...
11:00PM
11:15PM
11:30PM
11:45PM
12:00AM
12:15AM
12:30AM
12:45AM
Or with another step in the seconds-range:
>>> start = datetime.time(8, 5)
>>> stop = datetime.time(9, 12)
>>> step = datetime.timedelta(minutes = 3, seconds = 22)
>>> for s in ftimerange(start, stop, step): print(s)
...
08:05AM
08:08AM
08:11AM
08:15AM
08:18AM
08:21AM
08:25AM
08:28AM
08:31AM
08:35AM
08:38AM
08:42AM
08:45AM
08:48AM
08:52AM
08:55AM
08:58AM
09:02AM
09:05AM
09:08AM
Upvotes: 3
Reputation: 122376
You can adapt h
for a specific range:
['%s:%s%s' % (h, m, ap) for ap in ('am', 'pm') for h in ([9] + range(1,5)) for m in ('00', '15','30','45')]
However this won't produce 5.00pm as the range does not include the last time.
Upvotes: 0