Adding a user specified date to existing code - python

I'm a but stuck with being able to add a user defined date to this Days to Go code. Works well with a set date embedded. But can't get this to work with the input lines.
from datetime import datetime, time
b = input
event = (input('What is the name of your event?')) # input the name of the event
year = int(input('Enter a year')) # input the requires year
month = int(input('Enter a month')) # input the required month
day = int(input('Enter a day')) # input the required day
def date_diff_in_seconds(dt2, dt1):
timedelta = dt2 - dt1
return timedelta.days * 24 * 3600 + timedelta.seconds
def dhms_from_seconds(seconds):
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return (days, hours, minutes, seconds)
# Specified date
date1 = datetime.date(b[1], b[2], b[3])
# Current date
date2 = datetime.now()
print("\n%d days, %d hours, %d minutes, %d seconds" %
dhms_from_seconds(date_diff_in_seconds(date2, date1)))
print()

First, you wrongly used b=input. It means you want to use input function with function name b, such as event = b('what is the name of your event?').
Instead, you can assign values to b like b = (event, year, month, day) after getting information using input().
And you imported datetime module by from datetime import datetime you don't need to explitly say datetime.date, just date. However, you can use datetime rather than date here, as follows:
from datetime import datetime, time
#b = input -> wrong usage
event = (input('What is the name of your event? ')) # input the name of the event
year = int(input('Enter a year ')) # input the requires year
month = int(input('Enter a month ')) # input the required month
day = int(input('Enter a day ')) # input the required day
b = (event, year, month, day) # you can assign date values to b
def date_diff_in_seconds(dt2, dt1):
timedelta = dt2 - dt1
return timedelta.days * 24 * 3600 + timedelta.seconds
def dhms_from_seconds(seconds):
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return (days, hours, minutes, seconds)
# Specified date
date1 = datetime(b[1], b[2], b[3]) # not datetime.date()
# Current date
date2 = datetime.now()
print("\n%d days, %d hours, %d minutes, %d seconds" %
dhms_from_seconds(date_diff_in_seconds(date2, date1)))
print()
# if you want to print the event together:
print("\n%d days, %d hours, %d minutes, %d seconds left for %s" % (
dhms_from_seconds(date_diff_in_seconds(date2, date1)) + (event,)))
The result is like:
What is the name of your event? birthday
Enter a year 2022
Enter a month 03
Enter a day 19
0 days, 14 hours, 40 minutes, 2 seconds
0 days, 14 hours, 40 minutes, 2 seconds left for Sunday # in case that you print the event together

I think your problem is likely this line:
date1 = datetime.date(b[1],b[2],b[3])
Try changing it to this:
date1 = datetime.date(year, month, day, 0, 0, 0)

Related

How to calculate time difference in python?

Example:
9:43 - 17:27 - how many hours and minutes elapsed between those times ?
Here is one approach to get the number of total minutes:
from datetime import datetime
s = '9:30 - 14:00 ; 14:30 - 16:30'
sum(((b-a).total_seconds()/60 for x in s.split(' ; ')
for a,b in [list(map(lambda t: datetime.strptime(t, '%H:%M'), x.split(' - ')))]))
Output: 390.0
If you know that the time periods will never span midnight, then you could simply split the time strings with time.split(":") and do the math yourself with the hours and minutes.
However, the correct solution would be to import the datetime module and calculate the timedelta.
This example could be condensed. I intentionally made it verbose without knowing exactly how you're getting your inputs:
from datetime import datetime
times = [
"9:30",
"14:00",
"14:30",
"16:30"
]
#Just using today's date to fill in the values with assumption all times are on the same day.
year = 2022
month = 6
day = 9
date_times = []
for time in times:
split_time = time.split(":")
hour = split_time[0]
minutes = split_time[1]
timestamp = datetime.datetime.today(year=year, month=month, day=day, hour=hour, min=minutes)
date_times.append(timestamp)
total_seconds = 0
for i in range(1, len(date_times), 2):
delta = date_times[i] - date_times[i-1] # The timedelta object returned will have days, seconds, milliseconds
total_seconds += delta.days * 86400 + delta.seconds
hours = total_seconds // 3600 # Integer division
minutes = round((total_seconds % 3600) / 60) # Change depending on if you want to round to nearest, or always up or down.

How to convert object datetime.time.now() to object datetime.timedelta()?

I'm using the datetime.time.now() for the current time, i.e. I want to perform an operation that counts in the totals of the hours (e.g. 1h:45min - 0h:50min). I cannot convert the current time to the datetime.timedelta object.
There is no datetime.time.now() — you must mean datetime.now() which returns a datetime instance which has a year, month, and day as well as the time of day. If you want a different time on the same day you can use its attributes to construct one.
If you subtract two datetimes the result is a timedelta.
You can also subtract an arbitrary timedelta from a datetime (resulting in another datetime).
Note that timedelta instances only have the attributes days, seconds, and microseconds, so if you want to know how long they are in hours and minutes, you have to manually calculate them.
Here's an example of doing all of these things.
from datetime import datetime, timedelta
now = datetime.now() # Current time.
# Construct a time on the same day.
sunrise = datetime(now.year, now.month, now.day, hour=6, minute=58)
if sunrise > now: # Future
delta = sunrise - now
when = 'will be in'
ago = ''
else: # Past
delta = now - sunrise
when = 'happened'
ago = 'ago'
days = delta.days
seconds = delta.seconds
hours = delta.seconds//3600
minutes = (delta.seconds//60) % 60
print(f'sunrise {when} {hours} hours {minutes} minutes {ago}')
print(f'30 minutes before sunrise today is {sunrise - timedelta(minutes=30)}')
I think I've found it; I wanted to compare the current time with the sunrise and sunset that Python itself retrieved.
I've done it this way now (so the next one can do it too)
import datetime as dt
DTN = dt.datetime.now()
H = int(DTN .strftime("%H"))
M = int(DTN .strftime("%M"))
S = int(DTN .strftime("%S"))
t1 = dt.timedelta(hours= H, minutes= M, seconds=S)
t2 = dt.timedelta(hours= 1, minutes= 0, seconds=0)
if t1 > t2:
timeCal = t1-t2 }
elif t1<t2:
timeCal = t2-t1
else:
timeCal = t1+t2
print(timeCal)
actual time = 20:00:00
result: 19:00:00

This question is related to the datetime module of Python

I wrote a Python function that prints the number of days remaining in birthday of a user - the value of which is entered by the user. The code is as follows:
"""
Created on Thu Feb 20 16:01:33 2020
#author: hussain.ali
"""
import datetime as dt
import pytz
def days_to_birthday():
a = (input('Enter your birthday in YYYY, MM, DD format with the year being the current year:'))
td = dt.datetime.today()
#td2= td.replace(hour=0, minute =0, second =0, microsecond =0)
birthday = dt.datetime.strptime(a, '%Y,%m,%d')
days_to_birthday = birthday - td
print("There are", days_to_birthday, ' remaining until your next birthday!')
days_to_birthday()
This script or code works well except that it gives the number of days plus hours as well as minutes, seconds and even microseconds remaining until the next birthday.
The output seems like:
Enter your birthday in YYYY, MM, DD format with the year being the current year:2020,3,7
There are 15 days, 6:11:07.020133 remaining until your next birthday!
I want either only the days remaining to be displayed in the output
OR the output as:
There are 15 days, 6 hours, 11minutes, 07seconds, and 020133 microseconds remaining until your next birthday!
What one needs to do to attain the desired output? Please advise.
change your print statement to this code below.
print("There are", days_to_birthday.days, 'days remaining until your next birthday!')
timedelta doesn't have strftime() to format it so you can do one of two things:
get total_seconds() and calculate all values using divmod() or using // and %
total = days_to_birthday.seconds
rest, seconds = divmod(total, 60)
hours, minutes = divmod(rest, 60)
days = days_to_birthday.days
microseconds = days_to_birthday.microseconds
print('{} days {:02} hrs {:02} mins {:02} secs {:06} microseconds'.format(days, hours, minutes, seconds, microseconds))
get string 15 days, 6:11:07.020133, split it and use parts to create new string
days = days_to_birthday.days
parts = str(days_to_birthday).split(', ')[1].replace('.', ':').split(':')
print('{} days {} hrs {} mins {} secs {} microseconds'.format(days, *parts))
import datetime as dt
import pytz
#a = input('Enter your birthday in YYYY,MM,DD format with the year being the current year:')
a = '2020,06,01'
print('date:', a)
td = dt.datetime.today()
birthday = dt.datetime.strptime(a, '%Y,%m,%d')
days_to_birthday = birthday - td
print(days_to_birthday)
total = days_to_birthday.seconds
rest, seconds = divmod(total, 60)
hours, minutes = divmod(rest, 60)
days = days_to_birthday.days
microseconds = days_to_birthday.microseconds
print('{} days {:02} hrs {:02} mins {:02} secs {:06} microseconds'.format(days, hours, minutes, seconds, microseconds))
days = days_to_birthday.days
parts = str(days_to_birthday).split(', ')[1].replace('.', ':').split(':')
print('{} days {} hrs {} mins {} secs {} microseconds'.format(days, *parts))
Result
date: 2020,06,01
93 days, 21:35:15.056351
93 days 21 hrs 35 mins 15 secs 056351 microseconds
93 days 21 hrs 35 mins 15 secs 056351 microseconds

calculate difference between two time in hour

I want to calculate difference between two time in hours using django in sql db the time are stored in timefield.
I tried this:
def DesigInfo(request): # attendance summary
emplist = models.staff.objects.values('empId', 'name')
fDate = request.POST.get('fromDate')
tDate = request.POST.get('toDate')
if request.GET.get('empId_id'):
sel = attendance.objects.filter(empId_id=request.GET.get('empId_id'),)
for i in sel:
# print i.
# print i.outTime
# print i.inTime.hour,i.inTime.minute,i.inTime.second - i.outTime.hour,i.outTime.minute,i.outTime.second
ss = i.inTime.hour
ss1 = 12 - ss
mm = i.outTime.hour
mm1 = (12 + mm) - 12
print ss1 + mm1
Since i.inTime and i.outTime are time objects you cannot simply subtract them. A good approach is to convert them to datetime adding the date part (use today() but it is irrelevant to the difference), then subtract obtaining a timedelta object.
delta = datetime.combine(date.today(), i.outTime) - datetime.combine(date.today(), i.inTime)
(Look here: subtract two times in python)
Then if you want to express delta in hours:
delta_hours = delta.days * 24 + delta.seconds / 3600.0
A timedelta object has 3 properties representing 3 different resolutions for time differences (days, seconds and microseconds). In the last expression I avoided to add the microseconds but I suppose it is not relevant in your case. If it is also add delta.microseconds / 3600000000.0
Note that simply dividing seconds by 3600 would have returned only the integer part of hours avoiding fractions. It depends on your business rules how to round it up (round, floor, ceil or leave the fractional part as I did)
Using datetime objects: https://docs.python.org/2/library/datetime.html
A good stack overflow post on the topic How to get current time in Python
from datetime import datetime
now = datetime.now()
# wait some time
then = ... some time
# diff is a datetime.timedelta instance
diff = then - now
diff_hours = diff.seconds / 3600
You might want to play with this codes:
from datetime import datetime
#set the date and time format
date_format = "%m-%d-%Y %H:%M:%S"
#convert string to actual date and time
time1 = datetime.strptime('8-01-2008 00:00:00', date_format)
time2 = datetime.strptime('8-02-2008 01:30:00', date_format)
#find the difference between two dates
diff = time2 - time1
''' days and overall hours between two dates '''
print ('Days & Overall hours from the above two dates')
#print days
days = diff.days
print (str(days) + ' day(s)')
#print overall hours
days_to_hours = days * 24
diff_btw_two_times = (diff.seconds) / 3600
overall_hours = days_to_hours + diff_btw_two_times
print (str(overall_hours) + ' hours');
''' now print only the time difference '''
''' between two times (date is ignored) '''
print ('\nTime difference between two times (date is not considered)')
#like days there is no hours in python
#but it has seconds, finding hours from seconds is easy
#just divide it by 3600
hours = (diff.seconds) / 3600
print (str(hours) + ' Hours')
#same for minutes just divide the seconds by 60
minutes = (diff.seconds) / 60
print (str(minutes) + ' Minutes')
#to print seconds, you know already ;)
print (str(diff.seconds) + ' secs')
The easiest way through I achieve is the comment of Zac given above. I was using relativedelta like this
from dateutil import relativedelta
difference = relativedelta.relativedelta( date1, date2)
no_of_hours = difference.hours
but it did not give me correct result when the days changes. So, I used the approach expressed above:
no_of_hours = (difference.days * 24) + (difference.seconds / 3600)
Please note that you will be getting negative value if date2 is greater than date1. So, you need to swipe the position of date variables in relativedelta.

Python time format with three-digit hour

How can I parse the time 004:32:55 into a datetime object? This:
datetime.strptime("004:32:55", "%H:%M:%S")
doesn't work becaush %H expects two digits. Any way to add the third digit?
Three options :
s = "004:32:55"
from datetime import datetime
datetime.strptime(s[1:], "%H:%M:%S") # from second 0 to the end
datetime.strptime(s, "0%H:%M:%S") # add 0 in formatting
from dateutil import parser # use dateutil
parser.parse(s)
There are 24 hours in a day so you can divide and get the modulus to figure out how many days and hours are in the time, then subtract the days, this needs some tweaking will get you started.
s = "04:32:55"
s = s.split(":",1)
hours, days = divmod(int(s[0]),24)
new_time = "{}:{}".format(hours,s[1])
past = datetime.now() - timedelta(days=days)
final = "{} {}".format(past.date().isoformat(),new_time)
print datetime.strptime(final,"%Y-%m-%d %H:%M:%S")
I chose a more pragmatic approach in the end and converted the time stamp to seconds:
hours = (0 if time_string.split(":")[0] == "000" else int(time_string.split(":")[0].lstrip("0")) * 3600)
mins = (0 if time_string.split(":")[1] == "00" else int(time_string.split(":")[1].lstrip("0")) * 60)
secs = (0 if time_string.split(":")[2] == "00" else int(time_string.split(":")[2].lstrip("0")))
return hours + mins + secs
Converting back to hours, minutes, and seconds is easy with datetime.timedelta(seconds=123).
EDIT:
A better solution (thanks to Ben):
hours = int(time_string.split(":")[0]) * 3600
mins = int(time_string.split(":")[1]) * 60
secs = int(time_string.split(":")[2])
return hours + mins + secs

Categories