Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
from datetime import date
future = input("Enter a date(dd/mm/yyyy): ")
daystring = future[0:2]
monthstring = future[3:5]
yearstring = future[6:10]
today = (date.today())
month = date.today().month
year = date.today().year
day = date.today().day
if monthstring == "01" or "03" or "05" or "07" or "08" or "10" or "12":
if daystring > "31":
print("Invalid Date Entered")
if monthstring == "04" or "06" or "09" or "11":
if daystring > "30":
print("Invalid Date Entered")
months = ["Jan", "Feb", "Mar", "Apr", "May", "June",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
daysinmonth = [31, 29, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31]
if future < today or monthstring > "12":
print("Invalid Date Entered")
else:
layout = "%d/%m/%Y"
a = datetime.strptime(future, layout)
b = datetime.strptime(today, layout)
delta = a - b
print ("The difference between the inputted date and todays date is: ",delta.days, "days")
This code is to ask the user to input a date in the future and then the code should use that input and subtract the current date from it.
For example, today is 01/11/2014 and if the user inputs 03/11/2014 the output should be that the difference is 2 days.
However, I'm getting an error every time I input the future date.
import dateutil.parser as parser
import datetime
date1 = parser.parse(input("Enter Date:"))
print( (datetime.datetime.now() - date1).days )
dateutil is very good at parsing natural date strings ...
you will probably need to install dateutil
easy_install python-dateutil
if you want to not use dateutil as mentioned you can use strptime
def get_user_date(prompt="Enter Date:"):
while True:
try:
return datetime.datetime.strptime("%m/%d/%y",input(prompt))
except ValueError:
print( "Invalid Input!" )
this code I think will work in python 3
There are different things to be considered. Try to take in considerations these points
Check if the user is entering right datetime. You can use regular expression to do that. You can use RE module.
mat=re.match('(\d{2})[/](\d{2})[/](\d{4})$', str(future))
You should filter values between 1-12 for months, and between 1-31 for days. Then distinguish between months, and don't forget February in both cases (leap year or no). You can use calender module to check that.
t= calendar.monthrange(int(yearstring), 2) # This is to check if February has 29 or 28 (is leap year or no), you can do that by checking the day number of "datetime.date (int(yearstring), 3, 1) - datetime.timedelta (days = 1)"
Then, compare between two dates, you should use right time format for every date.
a = date.datetime.strptime(future, "%d/%m/%Y").date()
b = date.datetime.strptime(today, "%Y-%m-%d").date()
delta = a-b
Your code would look like:
import datetime as date
import re
import calendar
future = input("Enter a date(dd/mm/yyyy): ")
#eg: future="02/03/2015"
#print future
mat=re.match('(\d{2})[/](\d{2})[/](\d{4})$', str(future))
if mat is None:
print("Invalid Date Entered, try to enter a date in this form(dd/mm/yyyy) ")
else:
daystring,monthstring,yearstring= mat.groups()
today= str(date.datetime.now()).split(" ")[0]
year, month, day = today.split("-")
months = ["Jan", "Feb", "Mar", "Apr", "May", "June","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
daysinmonth = [31, 29, 31, 30, 31, 30, 31, 31, 30,31, 30, 31]
if int(daystring)>0 and int(daystring)<=31 and int(monthstring)>0 and int(monthstring) <= 12 and int(yearstring)>0:
if monthstring in ["01", "03", "05" ,"07","08","10", "12"]:
if int(daystring) > 31:
print("Invalid Date Entered - Number of days can't exceed 31.")
if monthstring in ["04","06","09","11"]:
if int(daystring) > 30:
print("Invalid Date Entered - Number of days can't exceed 31.")
if monthstring == "02":
t= calendar.monthrange(int(yearstring), 2) # This is to check if February has 29 or 28 (is leap year or no), you can do that by checking the day number of "datetime.date (int(yearstring), 3, 1) - datetime.timedelta (days = 1)"
if int(daystring) !=t: #You forget faberuary
print("Invalid Date Entered - of days can't exceed 28 or 29")
a = date.datetime.strptime(future, "%d/%m/%Y").date()
b = date.datetime.strptime(today, "%Y-%m-%d").date()
delta = a-b # The future - Today ::> to get a positive number
if delta.days >0:
print ("The difference between the inputted date and todays date is: ",delta.days, "days")
else:
print("Date is in the past")
else:
print("Invalid Date Entered")
Related
one of the revision questions was to create a function that checks if a date is valid or not and return a boolean. We were given the first two lines of the function, as so.
Edit: We are not allowed to use inbuilt functions that do all the work such as date.time
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
Where the days_in_month list contains the maximum day number for the respective months.
Test cases:
is_a_valid_date("January 28 6")) False
is_a_valid_date("January 21")) True
is_a_valid_date(" June 15B ")) False
Code so far:
def is_a_valid_date(date):
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
clean_date = date.split()
clean_date[1:] = ["".join(clean_date[1:])]
a = False
b = False
if clean_date[0] in month_names:
a = True
x = month_names.find(clean_date[0])
else:
a = a
if clean_date[1].isdigit() == True and int(clean_date[1]) <= int(days_in_month[x]):
b = True
else:
b = b
if a == True and b == True:
return True
else:
return False
I'm having trouble figuring out how to create a condition that sees if the date number inputted is <= the respective month's maximum date number if a = True. I tried using .find but it doesn't seem to work on lists and even then I'm not sure I implemented it properly.
You can simplify that condition like this:
def is_a_valid_date(date):
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October",
"November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
month, day = date.split(maxsplit=1)
if day.isdigit():
return int(day) <= days_in_month[month_names.index(month)]
return False
Get the name of the month and day from date. Use that name to find days count in days list. Then convert days to int and compare with value from that list. If day can't be converted to int just return False.
I suggest making a dictionary for every max. no. of days per month (eg. days_in_month={January:31,...} and use days_in_month.get(clean_date[0]) instead. so you don't need x also or clean_date[1]
I hope my answer is what you are looking for.
First I have a dictionary that contains all of the months and their max day number values. We check the inputted day value against the inputted month name using the dictionary month_dictionary and get() like this: if day > month_dictionary.get(month):. If the day value is larger than the month's max day value or smaller than 0, than the function returns False and tells you why (which you can delete if you want).
The second function just has a fancy line that makes inputting the date in easier. month, dayRAW = date.split(" ") splits the 1 inputted string into 2 variables, month and dayRAW when the program sees a space in the string. They will then be used in the same way as the first function (after converting the day string into a number, day = int(dayRAW)).
month_dictionary = {"January": 31,
"February": 28,
"March": 31,
"April": 30,
"May": 31,
"June": 30,
"July": 31,
"August": 31,
"September": 30,
"October": 31,
"November": 30,
"December": 31}
def is_a_valid_date_1(month, day):#Input the month with quotes
if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
print("Day number is too large")
return False
elif day <= 0:
print("Day number can't be zero or smaller")
return False
else:
print("This is a valid date")
return True
def is_a_valid_date_2(date):
month, dayRAW = date.split(" ")#Separates the date string when it sees a space
day = int(dayRAW)#Turns the string into a workable integer
if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
print("Day number is too large")
return False
elif day <= 0:
print("Day number can't be zero or smaller")
return False
else:
print("This is a valid date")
return True
It also appears mx0 has a condensed version of what I have written. Nice job mate.
I also hope this helps any other passing people :)
I have a string input where text contains data as "monday of next month" or "4 days before new year" need to convert into dates as suppose today is 25/11/2020, so next month monday is on 07/12/2020, so how should i do it in python (i've tried using datetime, dateutil but didn't help')
next week saturday
4 days before new year
3 days after new year
second wednesday of next month
i need output as
05/12/20
28/12/20
03/01/21
09/12/21
tried reading docs but didn't help can anyone shed some light on it.
here's my python code.
from datetime import datetime, timedelta
from dateutil import parser
from dateparser.search import search_dates
# Create your views here.
def converter_view(request):
form = DateStringForm()
if request.method == 'POST':
form = DateStringForm(request.POST)
if form.is_valid():
input_string = form.cleaned_data['string_date']
list_of_dates = []
if input_string.lower() == "today":
data = datetime.now()
list_of_dates.append(data.strftime('%d/%m/%Y'))
elif input_string.lower() == "tomorrow":
data = datetime.now() + timedelta(1)
list_of_dates.append(data.strftime('%d/%m/%Y'))
elif input_string.lower() == "yesterday":
data = datetime.now() - timedelta(1)
list_of_dates.append(data.strftime('%d/%m/%Y'))
else:
try:
# Using search_dates method we were extracting the keywords related to date, day or month
# So search_dates is going to return a "list of tuple" where 0th index is string and 1st is datetime
data = search_dates(input_string)
except Exception as msg:
print('Exception :', msg)
else:
try:
for i in data:
# So as we require to convert that date back in string format, we parse the extracted data in data
# where parser.parse() is taking 0th index which is string, and converting it to date and by using
# strftime function we get the required format
list_of_dates.append(parser.parse(i[0]).strftime('%d/%m/%Y'))
print(list_of_dates)
except TypeError as msg:
print("String does not contain any day or dates")
values = DateStringConvert(string_date=input_string, date=list_of_dates)
values.save()
return HttpResponseRedirect('/dateconverter')
return render(request, 'DateTimeConverter/index.html', {'form':form})
It's impossible to facilitate all possible combinations and pieces of text. However, you can cover most cases with a few basic patterns.
import re
import datetime
queries = [
"next week saturday",
"4 days before new year",
"3 days after new year",
"second wednesday of next month",
]
def parse_relative_string_date(text: str, start_date: datetime.datetime = datetime.datetime.now()) -> datetime.datetime:
def _next_week(weekday: str):
weekdays = {
"monday": 0,
"tuesday": 1,
"wednesday": 2,
"thursday": 3,
"friday": 4,
"saturday": 5,
"sunday": 6,
}
next_week = start_date + datetime.timedelta(weeks=1)
return next_week + datetime.timedelta((weekdays[weekday.lower()] - next_week.weekday()) % 7)
def _new_year(n_days: str, direction: str):
new_years = datetime.datetime(year=start_date.year + 1, month=1, day=1)
directions = {
"before": -1,
"after": 1,
}
return new_years + datetime.timedelta(directions[direction.lower()] * int(n_days))
patterns = {
r"next week (?P<weekday>\w+)": _next_week,
r"(?P<n_days>\d+) days (?P<direction>\w+) new year": _new_year,
# Add more patterns here
}
for pattern, callback in patterns.items():
found = re.search(pattern, text)
if found is not None:
return callback(**dict(found.groupdict()))
for query in queries:
print(parse_relative_string_date(query))
I wrote this script just for practice and for some reason there is an issue with the year returned after the customer enters their year of birth. For example, my friend was born in 1991 but in October. The code works fine for January but for October, it states that the NYE of that year (1991) was in 1992 for my friend's birthday (which is October 13th, 1991). Please advice!
I tried reading manual for year but not much offered. I googled, but this question is very vague.
from datetime import date
from datetime import time
from datetime import datetime
from datetime import timedelta
today = date.today() # date.var returns date
print '\nToday is', (today.strftime('%B')), (today.strftime('%d')), (today.strftime('%Y')) # time formats used to return mo, day, yr
print "\nHello! What is your name?"
user_name = raw_input('--> ')
print '\nHow old are you, %s?' % user_name
user_age = int(raw_input('--> '))
# Python lists start with 0 index so add in a dummy for 0
months = ['Dummy', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
print '\nWhat day, month and year were you born?'
user_day = int(raw_input('Day: ')) # use this line to get index from months list
user_month = months.index(raw_input('Month: '))
user_year = int(raw_input('Year: '))
date_birth = user_year, user_month, user_day
print '\nYou were born on', date_birth
NYE_birth = (today.year - user_age, 1, 1)
print 'The New Year\'s Eve of that year was ', NYE_birth
print 'You were born', user_month - 1, 'months and', user_day - 1, 'days after NYE.\n'
# need to include months
ry = 100 - user_age
age_cent = date (int(today.year + ry), int(user_month), int(user_day))
print '\nWow, a long way to go! You will turn 100 years-old on', age_cent
print '\n'
The expected outcome should be that NYE is the same year as user's year of birth. But it shows the following year.
Since your friend was born in October, 1991, he's still only 27 years old now, he'll be 28 after his next birthday. When you subtract 27 from the current year, it's 1992.
If the birthday is later in the year than when you run the program, you need to subtract an additional year to account for this.
if today.month > user_month or (today.month == user_month and today.day >= user_day):
NYE_birth = (today.year - user_age, 1, 1)
else:
NYE_birth = (today.year - user_age - 1, 1, 1)
You'll need to make a similar adjustment for the century year.
Of course, since you ask what year they were born, you could just user_year instead of calculating it from the age.
IIUC try using:
from datetime import date, time, datetime, timedelta
today = date.today() # date.var returns date
print '\nToday is', (today.strftime('%B')), (today.strftime('%d')), (today.strftime('%Y')) # time formats used to return mo, day, yr
print "\nHello! What is your name?"
user_name = raw_input('--> ')
print '\nHow old are you, %s?' % user_name
user_age = int(raw_input('--> '))
# Python lists start with 0 index so add in a dummy for 0
months = ['Dummy', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
print '\nWhat day, month and year were you born?'
user_day = int(raw_input('Day: ')) # use this line to get index from months list
user_month = months.index(raw_input('Month: '))
user_year = int(raw_input('Year: '))
date_birth = user_year, user_month, user_day
print '\nYou were born on', date_birth
NYE_birth = (user_year, 1, 1)
print 'The New Year\'s Eve of that year was ', NYE_birth
print 'You were born', user_month, 'months and', user_day, 'days after NYE.\n'
# need to include months
ry = 100 - user_age
age_cent = date (int(today.year + ry), int(user_month), int(user_day))
print '\nWow, a long way to go! You will turn 100 years-old on', age_cent
print '\n'
I am trying to get detailed calendar information on all my birthdays to 2024(i.e. week #, day of week etc...). I noticed Pandas as date_range function/method, but am trying to do it using time/datetime because I couldn't get "freq=" to work. This is what I have so far, and I think I can get what I need from myBirthdays list, but am wondering if there is/was an easier way? Seems like a lot of extra work.
TIA.
#import pandas as pd
from datetime import date
import time
def BdayList(birthdate, enddate):
print(birthdate, type(birthdate), endDate, type(endDate))
#print(birthdate.weekday(), endDate.isocalendar())
myMonth = date.strftime(birthdate, "%m")
myDay = date.strftime(birthdate, "%d")
myBirthDays = []
daysDelta = (enddate - birthdate)
daysDeltaInt = daysDelta.days / 365
for year in range(int(date.strftime(birthdate, "%Y")), int(date.strftime(enddate, "%Y"))): #13148
year = str(year)
myBirthday = time.strptime(year+" "+myMonth+" "+myDay, "%Y %m %d")
print(myBirthday)
myBirthDays.append(myBirthday)
#dateRange = pd.date_range(start, periods = NumPeriods, freq="A")
return myBirthDays#DaysDelta, type(DaysDelta)
myBday = date(1988, 12, 22)
endDate = date(2024, 12, 22)
BdayList(myBday, endDate)
time.struct_time(tm_year=1988, tm_mon=12, tm_mday=22, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=357, tm_isdst=-1)
Because it is possible to just replace the year in original birth_date, there is no need to switch between dates and strings. (Note that I have also PEP8'd the code and used slightly different variable names + added type hints)
from datetime import date
from typing import List
from pprint import pprint
def get_birthdays(birth_date: date, end_date: date) -> List[date]:
birthday_list = list()
while birth_date <= end_date:
birthday_list.append(birth_date)
birth_date = birth_date.replace(year=birth_date.year + 1)
return birthday_list
if __name__ == "__main__":
birthdays = get_birthdays(
birth_date=date(1988, month=12, day=22),
end_date=date(2024, month=12, day=22)
)
pprint([(x.strftime("%Y-%m-%d %A, week: %U")) for x in birthdays])
The output should be:
['1988-12-22 Thursday, week: 51',
'1989-12-22 Friday, week: 51',
'1990-12-22 Saturday, week: 50',
'1991-12-22 Sunday, week: 51',
'1992-12-22 Tuesday, week: 51',
'1993-12-22 Wednesday, week: 51',
'1994-12-22 Thursday, week: 51',
'1995-12-22 Friday, week: 51']
To format output, please check datetime documentation. Hopefully this helps!
I have a while loop and I need to not execute code beween 5pm est on friday and 5pm est on Sunday.
I get est time using the follow:
import datetime
from datetime import timedelta
from pytz import timezone
est = timezone('US/Eastern')
now_utc = datetime.datetime.now(timezone('UTC'))
now_est = now_utc.astimezone(est)
if firday5pm < now_est < suday5pm:
pass
So...how do I get firday5pm and suday5pm?
import datetime
from pytz import timezone
est = datetime.datetime.now(timezone('US/Eastern'))
day, hour = est.weekday(), est.hour
if (day == 5 and hour > 17) or (day == 6) or (day == 7 and hour <17):
print('Stop work. It is a weekend!')