Comparing 2 times and getting the difference in minutes - python

i am trying to get the time difference using two times. i am getting 2 epoch timestamps from an api, converting them to a datetime, and then trying to compare them and get the time difference in minutes.
No errors in console.. the minutes just stay at 0.0 when i return it.
onlinestatus = (data["session"]["online"])
if onlinestatus is False:
theNewLineString = "\n"
lastLogout_string = "LastLogout: "
log_in = int(data2["player"]["lastLogin"])
log_out = int(data2["player"]["lastLogout"])
log_in_converted = timedate = time.strftime('%Y-%m-%d\n%I:%M %p', time.localtime(log_in / 1000))
log_out_converted = timedate = time.strftime('%Y-%m-%d\n%I:%M %p', time.localtime(log_out / 1000))
diff = datetime.strptime(log_in_converted, '%Y-%m-%d\n%I:%M %p') - datetime.strptime(log_out_converted, '%Y-%m-%d\n%I:%M %p')
return str("Online: ") + "`" + "False" + "`" + theNewLineString + theNewLineString + lastLogout_string + "`" + log_out_converted + theNewLineString + "`" + "Minutes Since Last Logout: " + "`" + str(diff.seconds/60) + "`"
I know everything else works. I am using a discord bot to return everything and here is what it returns:
Online: False
LastLogout: 2020-05-16
12:27 PM
Minutes Since Last Logout: 0.0
Any help is appreciated!

Let's say you have 2 datetime objects:
d1 = datetime.datetime.now()
d2 = datetime.datetime.now()
Now you can substract one from the other:
(d2 - d1)
This gives the result:
datetime.timedelta(seconds=3, microseconds=516614)
Then you can call the 'seconds' item and convert it to minutes:
(d2 - d1).seconds / 60
Hope this helps.

Related

Question about dateutil.relativedelta - Why the ouput is always zero?

Why the output of this relativedelta attribute is also zero?
The data file contains two date time strings, the purpose is to get the time difference between the two.
# python3.6 time_diff.py
0
0
0
0
# cat data
06/21/2019 21:45:24 06/21/2020 21:45:26
06/21/2019 22:42:25 06/22/2020 01:28:41
06/21/2019 22:41:32 06/21/2020 22:42:32
06/20/2019 23:42:25 06/22/2020 02:42:29
# cat time_diff.py
import dateutil.relativedelta, datetime
f = open("data", "r")
for line in f:
t1 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
t2 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
rd = dateutil.relativedelta.relativedelta(t1, t2)
print(rd.seconds)
instead of
t1 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
t2 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
go with
t1 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
t2 = datetime.datetime.strptime(line.split()[2] + " " + line.split()[3], "%m/%d/%Y %H:%M:%S")
you are providing wrong input to t2. After splitting the input from the file becomes this ['06/21/2019', '21:45:24', '06/21/2020', '21:45:26'].
So t1 should get input 0 and 1 and t2 should get input 2 and 3.
Below is the updated code:
import dateutil.relativedelta, datetime
f = open("data", "r")
for line in f:
t1 = datetime.datetime.strptime(line.split()[0] + " " + line.split()[1], "%m/%d/%Y %H:%M:%S")
t2 = datetime.datetime.strptime(line.split()[2] + " " + line.split()[3], "%m/%d/%Y %H:%M:%S")
rd = dateutil.relativedelta.relativedelta(t1, t2)
print(t1, t2, rd.seconds)

Change to the previous day date in python

I'm working on my python script to get the strings from the button objects so I can use it to set the date formats with the time that I got from the strings to store it in the lists. When I get the strings from the button objects, I want to set the date for each string, example: 29/08/2017 11:30PM, 30/08/2017 12:00AM, 30/08/2017 12:30AM.
When I try this:
if day_date >= 0 and day_date <= 6:
if epg_time3 == '12:00AM':
if day_date > 0:
currentday = datetime.datetime.now() + datetime.timedelta(days = 0)
nextday = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
if currentday != nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
elif currentday == nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
It will show the output:
self.epg_time_1
['29/08/2017 11:00PM']
self.epg_time_2
['29/08/2017 11:30PM']
self.epg_time_3
['29/08/2017 12:00AM']
When I'm calling the EPG_Times function again, it will show the output like this:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['30/08/2017 12:00AM']
It should be:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['31/08/2017 12:00AM']
As you can see the time 12:00AM is the next day so I want to set it to 31 not 30. I have changed from days = self.program_day + 1 to days = self.program_day - 1, but when the strings show 11:00PM, 11:30PM and 12:00AM from the variables epg_time_1, epg_time_2 and epg_time_3, it will show the output like this:
self.epg_time_1
['30/08/2017 11:00PM']
self.epg_time_2
['30/08/2017 11:30PM']
self.epg_time_3
['30/08/2017 12:00AM']
Here is the full code:
self.program_day = list()
def EPG_Times(self):
self.epg_time_1 = list()
self.epg_time_2 = list()
self.epg_time_3 = list()
epg_time1 = str(self.getControl(344).getLabel())
epg_time2 = str(self.getControl(345).getLabel())
epg_time3 = str(self.getControl(346).getLabel())
day_date = self.program_day
day = ''
month = ''
year = ''
if day_date >= 0 and day_date <= 6:
if epg_time3 == '12:00AM':
if day_date == 0:
if epg_time1 == '12:00AM':
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
else:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
else:
currentday = datetime.datetime.now() + datetime.timedelta(days = 0)
nextday = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
if currentday != nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day + 1)
elif currentday == nextday:
epg_time_1 = datetime.datetime.now() + datetime.timedelta(days = self.program_day)
epg_time_2 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg_time_3 = datetime.datetime.now() + datetime.timedelta(days = self.program_day - 1)
epg1_day = epg_time_1.strftime("%d")
epg1_month = epg_time_1.strftime("%m")
epg1_year = epg_time_1.strftime("%Y")
epg2_day = epg_time_2.strftime("%d")
epg2_month = epg_time_2.strftime("%m")
epg2_year = epg_time_2.strftime("%Y")
epg3_day = epg_time_2.strftime("%d")
epg3_month = epg_time_2.strftime("%m")
epg3_year = epg_time_2.strftime("%Y")
half_hour = str(epg1_day + "/" + epg1_month + "/" + epg1_year + " " + epg_time1)
one_hour = str(epg2_day + "/" + epg2_month + "/" + epg2_year + " " + epg_time2)
one_hour_half = str(epg3_day + "/" + epg3_month + "/" + epg3_year + " " + epg_time3)
#Store the times and date in the list....
self.epg_time_1.append(half_hour)
self.epg_time_2.append(one_hour)
self.epg_time_3.append(one_hour_half)
What I'm expected the code to do is to change to the previous day date for each string that I get from the button objects when I call the EPG_time(self) function. If the epg_time_1 and epg_time_2 show the strings 11:00PM and 11:30PM, I want to set the time and date to 29/08/2017 11:00PM for epg_time_1 and 29/08/2017 11:30PM for the epg_time_2. If the epg_time_3 show the string 12:00AM then I want to add it to the next day date with the time 30/08/2017 12:00AM.
In the next 24 hours if the epg_time_1 and epg_time_2 show the strings 11:00PM and 11:30PM, I want to set the time and date to 30/08/2017 11:00PM for epg_time_1 and 30/08/2017 11:30PM for the epg_time_2. If the epg_time_3 show the string 12:00AM then I want to set to the next day date with the time 1/09/2017 12:00AM
If the epg_time_1 and epg_time_2 show the strings 11:30PM and 12:00AM, I want to change to the previous date for epg_time_1 which it is 29/08/2017 11:30PM and 30/08/2017 12:00AM. It will be depends on the time and date when I have stored the strings in the list.
Can you please tell me an example how I could use to change the date to the previous date and add to the next day date using in python?
There's a lot of text in your question that makes it hard to pinpoint the issue exactly. However, it appears to boil down to adding a variable number of days to a particular date and ensuring that the month is also updated (if necessary).
You should use the datetime.datetime.strptime() method to convert your dates to datetimes, which makes it trivial to add timedelta (you use both timedelta and strftime but miss this crucial method) and then just convert back to a string.
import datetime as dt
def add_days(datelist, days_to_add):
# Convert the strings to datetime objects
datelist = [dt.datetime.strptime(item, '%d/%m/%Y %I:%M%p')
for item in datelist]
# Add a variable number of days (can be negative) to the datetimes
mod_dates = [item + dt.timedelta(days=days_to_add) for item in datelist]
# Convert back to strings
str_dates = [dt.datetime.strftime(item, '%d/%m/%Y %I:%M%p')
for item in mod_dates]
return str_dates
# This is the list right at the top of your question
a = ['29/08/2017 11:30PM', '30/08/2017 12:00AM', '30/08/2017 12:30AM']
print("Start:")
print(a)
b = add_days(a, 1)
print("After 1 call:")
print(b)
c = add_days(b, 1)
print("After 2 calls:")
print(c)

Python timestamp to time since conversion

I have a database column the holds timestamps in UNIX format, I am looking for a way to compare those timestamps to a timestamp from the time right now and print how many seconds/hours/days since the original timestamp.
Just to confirm I am NOT looking for a conversion from 1489757456 to 03/17/2017 # 1:30pm. I AM looking for a conversion from 1489757456 to 1m ago/2hr ago/3d ago ect.
datetime.datetime.fromtimestamp()
to convert your unix timestamp to a datetitme
datetime.datetime.now()
to get the current datetime
dateutil.relativedelta.relativedelta(dt1, dt2, ...)
to get the difference with respect to leap years.
References:
https://docs.python.org/3.6/library/datetime.html
http://dateutil.readthedocs.io/en/stable/relativedelta.html
Function, like this will generate output for hours, mins and seconds from seconds number.
def secondsToHms(d):
d = int(d);
h = math.floor(d / 3600)
m = math.floor(d % 3600 / 60)
s = math.floor(d % 3600 % 60)
htext = " hour, " if h == 1 else " hours, "
hDisplay = str(h) + htext if h > 0 else ""
mtext = " minute, " if m == 1 else " minutes, "
mDisplay = str(m) + mtext if m > 0 else ""
stext = " second" if s == 1 else " seconds"
sDisplay = str(s) + stext if s > 0 else ""
return hDisplay + mDisplay + sDisplay;
For example:
secondsToHms(344334)
>> 95.0 hours, 38.0 minutes, 54.0 seconds
So you can add your preferred formatting and also add days/months if needed in similar fashion.

Python module does not work as expected, if used as custom keyword in Robot Framework

If I call this pathon function from console, the dates are calculated as expected:
def get_nearest_date(day, month):
"""Gets nearest date in the future for provided day and month."""
today = date.today()
res = ""
if (today.month < month):
res = str(day) + "." + str(month) + "." + str(today.year)
elif ((today.month == month) & (today.day < day)):
res = str(day) + "." + str(month) + "." + str(today.year)
else:
res = str(day) + "." + str(month) + "." + str((today.year + 1))
return res
for example:
print get_nearest_date(1, 1)
print get_nearest_date(1, 12)
returns
1.1.2016
1.12.2015
But if I use this function as custom keyword in a Robot Framework testcase like this
Bla
${d} = Get Nearest Date 1 1
Log To Console ${d}
${d} = Get Nearest Date 1 12
Log To Console ${d}
it prints
Bla
1.1.2015
1.12.2015
which is wrong (first date should be 2016). Why is this?
It took me some time to realise that in RF the parameters passed to my custom keyword
${d} = Get Nearest Date 1 1
are actually strings. Passing number variables solves this issue:
${d} = Get Nearest Date ${1} ${1}

Python Time Math

I want to write a program that allows the user to enter in a start time hour, end time hour, and number of divisions.
So they might enter 9, 10, and 4 which should mean a start time of 9:00AM, end of 10:00AM and to split the range 4 times, resulting in an output of 9:00, 9:15, 9:30, 9:45.
I've tried using the time module and datetime, but cannot get the addition of time to work. I do not care about date.
I can calculate the time split, but the actual addition to the start time is evading me.
I have a hodge-podge of code, and the following is mostly me experimenting trying to figure out how to make this work. I've tried adding the minutes, tried converting to seconds, delved into datetime, tried the time module, but can't seem to get it to work. There are plenty of examples of how to "add 15 minutes to now" but the issue is I don't want to start at the "now", but rather let the user decide start time.
Thank you.
time_start = "9"
time_end = "10"
time_split = "4"
if len(time_start) == 1:
time_start = "0" + str(time_start) + ":00"
else:
time_start = str(time_start) + ":00"
if len(time_end) == 1:
time_end = "0" + str(time_end) + ":00"
else:
time_end = str(time_end) + ":00"
print time_start
print time_end
s1 = time_start + ':00'
s2 = time_end + ':00'
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)
divided = tdelta / int(time_split)
print tdelta
print divided
s3 = str(divided)
print "s1 time start: " + str(s1)
print "s2 time end: " + str(s2)
print "s3 time divided: " + str(s3)
ftr = [3600,60,1]
add_seconds = sum([a*b for a,b in zip(ftr, map(int,s3.split(':')))])
print "s3 time divided seconds: " + str(add_seconds)
print "time delta: " + str(tdelta)
EDIT: I did a small bit of research and found a much better solution that elegantly handles resolution to the millisecond. Please implement this code instead (though I will save the old code for posterity)
import datetime
start_time = 9 # per user input
end_time = 10 # per user input
divisions = 7 # per user input
total_time = end_time - start_time
start_time = datetime.datetime.combine(datetime.date.today(),datetime.time(start_time))
end_time = start_time + datetime.timedelta(hours=total_time)
increment = total_time*3600000//divisions # resolution in ms
times = [(start_time+datetime.timedelta(milliseconds=increment*i)).time()
for i in range(divisions)]
from pprint import pprint
pprint(list(map(str,times)))
# ['09:00:00',
# '09:08:34.285000',
# '09:17:08.570000',
# '09:25:42.855000',
# '09:34:17.140000',
# '09:42:51.425000',
# '09:51:25.710000']
If I were you, I'd do my math as raw minutes and use datetime.time only to save the results as something more portable.
Try this:
import datetime
start_time = 9 # per user input
end_time = 10 # per user input
divisions = 4 # per user input
total_minutes = (end_time-start_time)*60
increment = total_minutes // divisions
minutes = [start_time*60]
while minutes[-1] < end_time*60:
# < end_time*60 - increment to exclude end_time from result
minutes.append(minutes[-1] + increment)
times = [datetime.time(c//60,c%60) for c in minutes]
# [09:00:00,
# 09:15:00,
# 09:30:00,
# 09:45:00,
# 10:00:00]

Categories

Resources