I've tried following examples such as https://www.pythonprogramming.in/get-range-of-dates-between-specified-start-and-end-date.html and Python generating a list of dates between two dates with various slightly different versions of the same code:
import datetime
from datetime import date, timedelta
def daterange():
while True:
d1 = input("Please enter in the earliest date: ")
check1 = d1.replace("-","")
if check1.isdigit:
d2 = input("Please enter in the latest date: ")
check2 = d2.replace("-","")
if check2.isdigit:
date1 = datetime.datetime.strptime(d1, '%d-%m-%Y').strftime('%Y,%m,%d')## this is to convert my intended input format
date2 = datetime.datetime.strptime(d2, '%d-%m-%Y').strftime('%Y,%m,%d')## this is to convert my intended input format
print (date1)
print (date2)
dd = [date1 + datetime.timedelta(days=x) for x in range (0,(date2-date1).days)]
print (dd)
return
else:
print("That was an invalid date")
else:
print("That was an invalid date")
And I'm getting the same error where it cannot do a subtraction in date2-date1:
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Can anyone explain why and provide a solution?
You can't add a timedelta to a str, which is what you are doing. This line: date1 = datetime.datetime.strptime(d1, '%d-%m-%Y').strftime('%Y,%m,%d') creates a datetime obj, and then converts it back to str.
Change your code like so and it will work:
import datetime
from datetime import date, timedelta
def daterange():
while True:
d1 = input("Please enter in the earliest date: ")
check1 = d1.replace("-","")
if check1.isdigit:
d2 = input("Please enter in the latest date: ")
check2 = d2.replace("-","")
if check2.isdigit:
date1 = datetime.datetime.strptime(d1, '%d-%m-%Y')
date2 = datetime.datetime.strptime(d2, '%d-%m-%Y')
print (date1)
print (date2)
dd = [date1 + datetime.timedelta(days=x) for x in range (0,(date2-date1).days)]
print (dd)
return
else:
print("That was an invalid date")
else:
print("That was an invalid date")
if __name__ == '__main__':
daterange()
Related
What I'm trying to do is get an input in the YYYY-MM-DD specific format and it will output the amount of minutes someone has lived since their birthdate. But the function "invalidate" only seems to create errors. Without it the code works as long as you input the correct format. I've tried some regex code but haven't been able to make it work either. Also, would it be easier to do this within a class?
import datetime
import inflect
import sys
import re
##class Date:
##def __init__(self, year, month, day):
def main():
birth = input("Birthdate: ")
##birthdate = invalidate(birth)
print(num_to_words(days_between(format_date(birth))) + " minutes")
##def invalidate(x):
#if x != "%Y-%m-d":
#sys.exit("Invalid")
def format_date(e):
year, month, day = map(int, e.split('-'))
date1 = datetime.date(year, month, day)
return date1
def days_between(f):
today = datetime.date.today()
diff = today - f
x = diff.days * 24 * 60
return x
def num_to_words(x):
p = inflect.engine()
words = p.number_to_words(x)
return words
if __name__ == "__main__":
main()
You need to check it with strptime to see if it actually matches the format, not the exact string:
import datetime
def invalidate(x):
# You were missing the % on d
try:
datetime.datetime.strptime(x, r'%Y-%m-%d')
except ValueError:
return False # Or change this to exit
return True # You could return your datetime object here too
>>> invalidate('2022-06-05')
True
>>> invalidate('2022-6-05')
True
>>> invalidate('')
False
>>> invalidate('2022')
False
In your original function, you were checking the exact match of the string:
>>> invalidate('%Y-%m-d') # This was the only thing that would match
>>> invalidate('2022-6-5')
Invalid
Modify your invalidate function to this:
def invalidate(x):
if re.match(r'^\d{4}-\d{2}-\d{2}$', x):
if datetime.datetime.strptime(x, '%Y-%m-%d'):
return datetime.datetime.strptime(x, '%Y-%m-%d')
else:
print("Invalid date")
sys.exit()
else:
print("Invalid date")
sys.exit()
I have modified my code which now has an additional valid date check after valid format check.
my first code i have written whilst learning, and have become stuck on one issue.
NAME=str(input("Enter your name: "))
print ("hello",NAME)
from datetime import *
today = date.today()
print("Today: " + today.strftime('%A %d, %b %Y'))
good_value = False
value = ""
while good_value == False:
value = input("Insert Date in format dd/mm/yyyy: ")
try:
datetime.strptime(value, '%m/%d/%Y')
good_value = True
except ValueError:
print("Error: Date format invalid.")
thisYear = today.year
dob_data = value.split("/")
dobDay = int(dob_data[0])
dobMonth = int(dob_data[1])
ÁdobYear = int(dob_data[2])
dob = date(thisYear,dobMonth,dobDay)
if today == date(thisYear,dobMonth,dobDay):
print ("happy bithday", NAME)
else:
print ("its not your birthday, sucks to be you")
when i run the code it will work perfectly unless i type the date being over the 12th, so not breaking the error loop and obviously limiting the dates that can be put into the finished product.
Here
value = input("Insert Date in format dd/mm/yyyy: ")
you are informing user that format should be DD/MM/YYYY, but here
datetime.strptime(value, '%m/%d/%Y')
you are expecting MM/DD/YYYY. In order to repair this replace former using
value = input("Insert Date in format mm/dd/yyyy: ")
and
dobDay = int(dob_data[0])
dobMonth = int(dob_data[1])
using
dobDay = int(dob_data[1])
dobMonth = int(dob_data[0])
Observe that this did worked for values equal or less than 12 as there are 12 months
I'm trying to make it so that it checks if its in the format I want and if its greater than today's date. I want it to ask for input until it gets a right answer but I can't find a way to do so.
while True:
try:
x=dt.datetime.strptime(input(), '%d/%m/%Y')
break
except ValueError:
print(1)
You can use the today class method to get a datetime object representing today's date, and use the > or < operator to compare it to the parsed x:
while True:
try:
x = dt.datetime.strptime(input(), '%d/%m/%Y')
if x > dt.datetime.today():
break
else:
print('before today')
except ValueError:
print('wrong format')
from datetime import datetime, date
while True:
input_ = input('Enter a date -> ')
try:
dt = datetime.strptime(input_, '%d/%m/%Y').date()
except ValueError:
dt = None
today = date.today()
if dt and dt > today:
break
print('All good!')
->
Enter a date -> 12/01/2021
Enter a date -> 18/01/2021
Enter a date -> 25/01/2021
Enter a date -> 14/02/2021
All good!
Customized your existing code to handle - a) Valid Date Check b) Greater than Today's Date condition.
import datetime as dt
while True:
try:
x = dt.datetime.strptime(input(), '%d/%m/%Y')
if x > dt.datetime.now():
print(x)
break
else:
print("Please Enter a Valid Date:")
except ValueError:
print("Invalid Date Format")
My solution;
import datetime as dt
todays_date = dt.datetime.now()
todays_seconds = todays_date.timestamp()
done = False
while not done:
user_input = input(f"Please type a date later that today's date ({todays_date.strftime('%d/%m/%Y')}): ")
try:
x = dt.datetime.strptime(user_input, '%d/%m/%Y')
if x.timestamp() <= todays_seconds:
print("Date must be after today's date")
else:
done = True
except ValueError:
print('Input not understood, please try again')
Gives;
Please type a date later that today's date (30/01/2021): 30/01/2021
Date must be after today's date
Please type a date later that today's date (30/01/2021): 31/01/2021
Process finished with exit code 0
enter image description heredef main():
date_tokens = date_input.split('/')
day = int(date_tokens[0])
month = int(date_tokens[1])
year = int(date_tokens[2])
if 1/1/1990<=31/12/2020 :
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
main()
python's datetime object is your friend: Datetime Documentation
It allows you to easily make calculations on dates, including comparisons like you want.
import datetime
date_input = datetime.date(year, month, day)
if date_input > datetime.date(1990, 1, 1) and date_input < datetime.date(1990, 12, 31):
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
Also, if you want user to keep entering dates you may want to do that inside a loop or of course put the input inside date_input:
def main():
date_input = input ('Date: ')
date_tokens = date_input.split('/')
day = int(date_tokens[0])
month = int(date_tokens[1])
year = int(date_tokens[2])
date_input = datetime.date(year, month, day)
if date_input > datetime.date(1990, 1, 1) and date_input < datetime.date(1990, 12, 31):
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
main()
main()
(I got a bit lazy so I just called main() again. Same result expect for another "Date: " print)
The whole code would be:
from datetime import date
date_tokens = date_input.split("/")
if date(1990,1,1) <= date(int(date_tokens[0]), int(date_tokens[1]), int(date_tokens[2])) <= date(2020,12,31):
date_input = input('Date: ')
else:
input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 ")
def checkdob():
while True:
dob = input("Date of Birth")
try:
dob == datetime.datetime.strptime(dob, '%d-%m-%y')
break
except:
print("Incorrect data format, should be DD-MM-YYYY")
checkdob()
I did the following and it works fine. I wonder what you enter as a DOB as an input. Otherwise, it seems to be working fine.
>>> from datetime import datetime
>>> dob = '31-12-99'
>>> if dob:
... dt_obj = datetime.strptime(dob, '%d-%m-%y')
...
>>> print dt_obj
1999-12-31 00:00:00
You can try like this:
def checkdob(dob):
try:
return datetime.datetime.strptime(dob, '%d-%m-%Y')
except ValueError:
print("Incorrect data format, should be DD-MM-YYYY")
return None
while not checkdob(input("Date of Birth")):
pass