I need to check how many seconds are lef to the nearest HH:MM time in Python (in 24 hour format). For example, now is 10:00 - I need to check 16:30 same day.
If its 18:00 I need to check secods left to the 16:30 next day end so on.
You probably want to use the datetime module, timeldelta is your friend here:
import datetime
def cal_delta_to(hour, minute):
now = datetime.datetime.now()
target = datetime.datetime(*now.timetuple()[0:3], hour=16, minute=30)
if target < now: # if the target is before now, add one day
target += datetime.timedelta(days=1)
diff = now - target
return diff.seconds
Start with simple steps. Programming is usually about breaking down tasks like these into steps.
Get current time. Get next 16:30. Subtract.
# use datetime
from datetime import datetime, timedelta
# get current time
curr = datetime.now()
# create object of nearest 16:30
nearest = datetime(curr.year, curr.month, curr.day, 16, 30)
# stupidly check if it's indeed the next nearest
if nearest < curr:
nearest += timedelta(days=1)
# get diff in seconds
print (nearest - curr).seconds
If your format is ensured, you can easily calculate the seconds of the day:
def seconds_of_day(hhmm):
return int(hhmm[:2])*3600 + int(hhmm[3:])*60
Having done this the comparison is straightforward:
t1 = seconds_of_day('16:30')
t2 = seconds_of_day('10:00')
#t2 = seconds_of_day('18:01')
diff = 86400-t2+t1 if t1<t2 else t1-t2
Use datetime:
import datetime
func = lambda s: datetime.datetime.strptime(s, '%H:%M')
seconds = (func(s2)-func(s1)).seconds
You can always get what you want, even in the special 'next day' cases, like in case1 below;
# case1: now is '09:30', check seconds left to the 09:29 next day
>>> (func('09:29')-func('09:30')).seconds
86340
# case2: now is '09:30', check 10:30 the same day
>>> (func('10:30')-func('09:30')).seconds
3600
Related
Let's assume I have two times with no date as shown below.
>>> time_1 = datetime.datetime.strptime("05:30", "%H:%M")
>>> time_2 = datetime.datetime.strptime("05:00", "%H:%M")
To compare these two, I can simply do this:
>>> time_1<= time_2
False
Now, for this example when I know 03:30 happens before "23:30", I get False as well.
>>> time_1=datetime.datetime.strptime("23:30", "%H:%M")
>>> time_2=datetime.datetime.strptime("03:30", "%H:%M")
>>> time_1<= time_2
False
I am trying to know if there is any way to handle this situations?
if time2 < time1:
time2 += datetime.timedelta(days=1)
assuming the second time is always the next day if it is less than the first time
assuming the time strings represent a time series, i.e. they appear in chronological order, one can derive datetime by adding as duration to an arbitrary date (I have to revise my comment #Selcuk ...). Something like
from datetime import datetime, time, timedelta
# assuming the "cyclic time" looks similar to this:
cycletimes = ["05:00", "05:30", "23:30", "03:30"]
# we can convert to timedelta;
# to_td converts HH:MM string to timedelta
to_td = lambda s: timedelta(hours=int(s.split(':')[0]), minutes=int(s.split(':')[1]))
durations = list(map(to_td, cycletimes))
# take an arbitrary date
refdate = datetime.combine(datetime.today().date(), time.min)
# what we want is datetime; we can already set the first entry
datetimes = [refdate+durations[0]]
# now we iterate over cycle times; if the next value is smaller, we add a day to refdate
for t0, t1, d in zip(cycletimes[:-1], cycletimes[1:], durations[1:]):
if t1 < t0:
refdate += timedelta(1)
datetimes.append(refdate+d)
print(f"{datetimes[0]} <= {datetimes[1]} -> {datetimes[0] <= datetimes[1]}")
# 2021-08-26 05:00:00 <= 2021-08-26 05:30:00 -> True
print(f"{datetimes[2]} <= {datetimes[3]} -> {datetimes[2] <= datetimes[3]}")
# 2021-08-26 23:30:00 <= 2021-08-27 03:30:00 -> True
Now for example "23:30" appears before "03:30", not after as if you'd only compare time. Side note, pure Python is great to illustrate the logic here; in the "real world" however I'd suggest to have a look at the pandas library for such a task.
I have a variable holding information about time (not current time) in the YYYYMMDDHHMMSS format.
I have a starting point and a finish point. Lets say '20210419000100' and '20210419130100'. Thats 13 hours from start to finish.
I want to save a string of this time for every 15 mins. ie we start at '20210419000100' and 15 mins later it will be '20210419001600'.
Obviously its not always +1500. I know its a long shot, but is there a tool for that or how could i do that in a generic way that would work with any starting point I would choose? It could be done only in HHMMSS format if its easier but if possible I would like the year/month/day to change, too.
I am more interested in a python solution.
python-dateutil to the rescue!
from dateutil import parser, relativedelta
START_DATE = '20210419000100'
END_DATE = '20210419130100'
start = parser.parse(START_DATE)
end = parser.parse(END_DATE)
while start < end:
print(start.strftime("%Y%m%d%H%M%S"))
start += relativedelta.relativedelta(minutes=15)
No need to install other dependencies, you can use python's standard datetime module
from datetime import datetime, timedelta
time_str = '20210419000100'
time_obj = datetime.strptime(time_str, '%Y%m%d%H%M%S')
print(time_obj)
# 2021-04-19 00:01:00
# If you want to add hours or minutes
def seconds(h = 0, m = 0, s = 0):
return h * 3600 + m * 60 + s
time_obj += timedelta(0, seconds(m=15)) # days, seconds
print(time_obj)
# 2021-04-19 00:16:00
# In case you want to convert it back
new_time_str = time_obj.strftime("%Y%m%d%H%M%S")
print(new_time_str)
# 20210419001600
I am trying to get get the time delta i minutes from two different time values.
time1 = 2020-11-28T10:31:12Z
time2 = 2020-11-28T09:10:23.203+0000
Then i will make i condition: if time difference is bigger then x minutes, run code...
Anyone have a solution for that.
I have tried using datetime.datetime.strptime() but cant get them on same format.
Thanks
Using date parser to let it figure out the date format
Code
from dateutil.parser import parse
def time_difference(time1, time2):
# Parse strings into datetime objects
dt1 = parse(time1)
dt2 = parse(time2)
# Get timedelta object
c = dt1 - dt2
# Difference in minutes
return (c.total_seconds()/60)
Test
time1 = "2020-11-28T10:31:12Z"
time2 = "2020-11-28T09:10:23.203+0000"
print(time_difference(time1, time2))
# Output: 80.81328333333333
well assuming you don't need split seconds you could do something like that:
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
import time
import datetime
def get_timestamp(time_str):
time_splited = time_str.split('T')
time_str_formatted = ' '.join([time_splited[0],time_splited[1][:8]])
return time.mktime(datetime.datetime.strptime(time_str_formatted,"%Y-%m-%d %H:%M:%S").timetuple())
print(get_timestamp(time1))
print(get_timestamp(time2))
reformatting both times to the same time format.
then your condition would look like:
if abs(get_timestamp(time1) -get_timestamp(time2) ) > x*60:
do_something(....)
The times are not uniform so you will have to make them the same to use strptime. For accuracy I prefer to convert to seconds then you can also at a later stage compare seconds, minutes or hours if you needed to.
import datetime
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
def minutes_diff():
#Make the times uniform so you can then use strptime
date_time1 = datetime.datetime.strptime(time1[:-1], "%Y-%m-%dT%H:%M:%S")
date_time2 = datetime.datetime.strptime(time2[:-9], "%Y-%m-%dT%H:%M:%S")
#Convert to seconds for accuracy
a_timedelta = date_time1 - datetime.datetime(1900, 1, 1)
b_timedelta = date_time2 - datetime.datetime(1900, 1, 1)
seconds_time_a = a_timedelta.total_seconds()
seconds_time_b = b_timedelta.total_seconds()
#Take one from each other for minutes
time_in_minutes = (seconds_time_a - seconds_time_b) / 60
#Then decide what to do with it
if time_in_minutes < 60: # 1 hour
print('Less than an hours do something')
else:
print('More than an hour do nothing')
minutes_diff()
DARRYL, JOHNNY and MARCIN, thanks for your solutions, problem solved!!
Andy
I have been thinking to do a sleep function where it sleeps until a certain date is called. My idea was based of date such as : 2019-01-20 12:00:00.
I haven't really figured out how to start to solve this problem. My idea was something similar such as
if there is a date given:
time.sleep(until the date and time)
So the question is how can I possibly be able to sleep until a certain time given in a value of 2019-01-20 12:00:00?
Easy, calculate how long it is, and sleep the time.
You can calculate how long it takes until your wakeup time is reached and sleep for the delta time.
Python can calculate with time intervals. If you subtract one timestamp from another, then you get a datetime.timedelta:
import datetime
import time
target = datetime.datetime(2019,1,20,12,0,0)
now = datetime.datetime.now()
delta = target - now
if delta > datetime.timedelta(0):
print('will sleep: %s' % delta)
time.sleep(delta.total_seconds())
print('just woke up')
of course, you can put that in a function:
import datetime
import time
target = datetime.datetime(2019,1,20,12,0,0)
def sleep_until(target):
now = datetime.datetime.now()
delta = target - now
if delta > datetime.timedelta(0):
time.sleep(delta.total_seconds())
return True
sleep_until(target)
You can check the return value: only if it slept, it returns True.
BTW: it's OK, to use a date in the past as target. This will generate a negative number of seconds. Sleeping a negative value will just not sleep.
if your time is a string, use this:
target = datetime.datetime.strptime('20.1.2019 20:00:00', '%d.%m.%Y %H:%M:%s')
or
target = datetime.datetime.strptime('2019-1-20 20:00:00', '%Y-%m-%d %H:%M:%s')
I did your problem in an efficient way:
import time, datetime
# given_date --> Your target time and date
dur = time.mktime(datetime.datetime.strptime(given_date, "%d-%b-%y %H:%M:%S").timetuple()) - time.time()
time.sleep(dur)
you mean something like this:
from time import sleep
from datetime import datetime
x = datetime.datetime.strptime('2019-01-20 12:00:00', '%Y-%m-%d %H:%M:%S')
y = datetime.now()
sleep((max(x,y) - min(x,y)).seconds)
You can use a while loop.
import datetime
_theday="01/01/2019"
while datetime.today() != _theday:
some stuff
I'm trying to get my head around the datetime module. I know the time now as an epoch and the time an event last happened (as an epoch time). What I need to do is figure out whether that event happened between midnight and midnight of yesterday.
t = time.time() # is now
t2 = 1234567890 # some arbitrary time from my log
24 hours ago is t - 86400, but how can I round that up and down to midnight. I'm having real trouble finding a way to get timestamps in and out of datetime or then manipulating a datetime to set the time.
In the Middle of the Night
Generating the last midnight is easy:
from datetime import datetime, time
midnight = datetime.combine(datetime.today(), time.min)
That combines today's date (you can use date() or a datetime() instance, your pick), together with time.min to form a datetime object at midnight.
Yesterday
With a timedelta() you can calculate the previous midnight:
from datetime import timedelta
yesterday_midnight = midnight - timedelta(days=1)
That Was Yesterday
Now test if your timestamp is in between these two points:
timestamp = datetime.fromtimestamp(some_timestamp_from_your_log)
if yesterday_midnight <= timestamp < midnight:
# this happened between 00:00:00 and 23:59:59 yesterday
All Together Now
Combined into one function:
from datetime import datetime, time, timedelta
def is_yesterday(timestamp):
midnight = datetime.combine(datetime.today(), time.min)
yesterday_midnight = midnight - timedelta(days=1)
return yesterday_midnight <= timestamp < midnight:
if is_yesterday(datetime.fromtimestamp(some_timestamp_from_your_log)):
# ...
Midnight at the start of today is:
midnight = (int(time.time() // 86400)) * 86400
so yesterday's midnight is:
midnight = (int(time.time() // 86400)) * 86400 - 86400
Given such a timestamp, you can use divmod to compute the number of days since the epoch (which you don't care about), and how many seconds are leftover (which you do):
days_since, remaining_seconds = divmod(t, 24*3600) # Divide by number of seconds in one day
Then, you subtract the leftover seconds from your original timestamp, which produces midnight
of the current day.
t -= remaining_seconds
Rounding up is as simple as shifting your target timestamp forward exactly one day before rounding down.
tomorrow_t = t + 24 * 3600
days_since, remaining_seconds = divmod(tomorrow_t, 24*3600)
t = tomorrow_t - remaining_seconds
To get the specific timezone's midnight timestamp:
from datetime import datetime
import pytz
TZ = "Asia/Shanghai"
datetime.now(pytz.timezone(TZ)).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()
In my estimation, many date and time manipulations are easier to do, and to understand, using the arrow library. This is one of them.
Create an arbitrary date and time.
>>> import arrow
>>> arbitrary = arrow.get(2017,8,16,11,5)
Calculate midnight_yesterday: first, midnight of arbitrary as its 'day' floor; then shift this back by one day. Display the result.
>>> midnight_yesterday = arbitrary.floor('day').shift(days=-1)
>>> midnight_yesterday
<Arrow [2017-08-15T00:00:00+00:00]>
Use timestamp for the desired overall result, for Python 3.3+.
>>> midnight_yesterday.datetime.timestamp()
1502755200.0
Or use this expression for Python 2.7. (Credit: https://stackoverflow.com/a/11743262/131187 for the latter two expressions.)
>>> (midnight_yesterday-arrow.get(1970,1,1)).total_seconds()
1502755200.0
You can use this code:
import time
seconds_of_day = 24 * 60 * 60 # 86400
last_midnight = (round(time.time()) // seconds_of_day) * seconds_of_day
yesterday_last_midnight = last_midnight - seconds_of_day
import time
start_str = time.strftime( "%m/%d/%Y" ) + " 00:00:00"
end_str = time.strftime( "%m/%d/%Y ") + " 23:59:59"
start_ts = int( time.mktime( time.strptime( start_str, "%m/%d/%Y %H:%M:%S" ) ) )
end_ts = int( time.mktime( time.strptime( end_str, "%m/%d/%Y %H:%M:%S" ) ) )
print (start_ts) # timestamp today at 00:00:00
print (end_ts) # timestamp today at 23:59:59
# 1552435200
# 1552521599
Source Python get unix epoch for today’s midnight and today’s 23:59:59 (start of day, end of day)