How to get user input as date format - python

I am trying to create a program to handle my finances, and one issue I always seem to have is not being able to input a date from the user interface, then subtracting or adding it to the current date to determine if it is overdue or coming soon.
How can I achieve this?
I tried converting the string to an int and float, and it comes up with a ValueError: invalid literal for int() with base 10: '(date here)'.
date = datetime.today().strftime('%d/%m/%Y')
show_str("Today's date is:\n-> " + str(date) +"\n")
biller_name = get_str("What is the billers name?\n-> ")
due_date = get_int("When is your bill due?\n(Enter date as \"DD/MM/YYYY\")\n-> ")
if due_date < date:
userDate = datetime(due_date)
x = userDate - date
print(x)

using datetime object you can easily check for due or coming soon.
Code:
from datetime import datetime
date_format = "%d/%m/%Y"
usr_input=input("When is your bill due?\n(Enter date as \"DD/MM/YYYY\")\n-> ")
today_date=datetime.today().strftime(date_format)
today_date = datetime.strptime(today_date, date_format)
due_date = datetime.strptime(usr_input, date_format)
x = abs(today_date-due_date)
if due_date<today_date:
print(f"{x.days} Days Overdue")
elif due_date>today_date:
print(f"{x.days} Days: Remaining")
else:
print("Today is the last date")
Output:
When is your bill due?
(Enter date as "DD/MM/YYYY")
-> 04/02/2023
Today is the last date
When is your bill due?
(Enter date as "DD/MM/YYYY")
-> 08/09/2023
216 Days: Remaining
When is your bill due?
(Enter date as "DD/MM/YYYY")
-> 12/04/2022
298 Days Overdue
Note* I obtained in days if you wanted you can change as your desired.. [months, years etc.]

Related

Python, format() function

Months={"01":"January","02":"February","03":"March","04":"April","05":"May","06":"June","07":"July","08":"August","09":"September","10":"October","11":"November","12":"December"}
date_time = lambda D: "{day} {month} {year} year {hour} hour"+"{p1} "+"{minute} minute"+"{p2}".format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')
how it should work :
date_time("01.01.2000 00:00") == "1 January 2000 year 0 hours 0 minutes"
how it does work:
date_time("01.01.2000 00:00") == "{day} {month} {year} year {hour} hour{p1} {minute} minute{p2}"
If you must do it yourself, try f-strings?
MONTHS={1:"January", 2:"February", 3:"March", 4:"April", 5:"May", 6:"June", 7:"July", 8:"August", 9:"September", 10:"October", 11:"November", 12:"December"}
def format(day, month, year, hour, minute):
return f"{day} {MONTHS[month]} {year} {hour} hour{('s' if hour > 1 else '')} {minute} minute{('s' if minute > 1 else '')}"
Otherwise, Python has a builtin package called datetime which may be of use...
You're only calling format() on the last string "{p2"} because . has higher precedence than +. You need to put the concatenations in parentheses.
date_time = lambda D: ("{day} {month} {year} year {hour} hour"+"{p1} "+"{minute} minute"+"{p2}").format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')
Although I don't understand why you're concatenating a bunch of literal strings. Just make it one long string.
date_time = lambda D: "{day} {month} {year} year {hour} hour{p1} {minute} minute{p2}".format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')
It is better if you use Template from string.
# import Template
from string import Template
date = "01.01.2000 00:00"
day = date.split('.')[0]
month = date.split('.')[1]
year = date.split('.')[2].split(' ')[0]
p1 = date.split(' ')[1].split(':')[0]
p2 = date.split(':')[1]
Months={
"01":"January",
"02":"February",
"03":"March",
"04":"April",
"05":"May",
"06":"June",
"07":"July",
"08":"August",
"09":"September",
"10":"October",
"11":"November",
"12":"December"
}
# Creating Template
template = Template("$day $month $year year $hour hours $minute minutes")
# Using Template
date = template.substitute({
'day' : int(day),
'month' : Months[month],
'year' : year,
'hour' : int(p1),
'minute' : int(p2),
})
print(date) # 1 January 2000 year 0 hours 0 minutes
The datetime module exists for this purpose, use it!
from datetime import datetime
dt = datetime.strptime("01.01.2000 00:00", "%m.%d.%Y %H:%M")
print(dt.strftime("%-m %B %Y year %-H hours %-M minutes"))
Output:
1 January 2000 year 0 hours 0 minutes

Know which parts a day contains

The dateparser library set missing parts of a date to today's values.
Example:
>>> import dateparser
>>> dateparser.parse("2015")
datetime.datetime(2015, 2, 14, 0, 0)
How to know which parts a date really contains?
(and thus which parts were set to today's values by the library)?
This is what I've come up with.
Is there a more efficient way?
date_str = input('Type a date: ')
settings = {"REQUIRE_PARTS": ["year"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Invalid Date")
return
settings = {"REQUIRE_PARTS": ["year", "month"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year only")
return
settings = {"REQUIRE_PARTS": ["year", "month", "day"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year and month")
return
print("Date has year, month and day")

Compare only today's date without hours/min/sec

I want to compare todays time with another new time without hour/min or seconds. Ignore hour and minutes...
In other words if both days are the same no matter hours or minutes it is ok (Extra) otherwise it is not good (Too old)... I tried but even with the same day still continue to compare with hour/min and sec. How can I do it?
import datetime
currentdate = datetime.datetime.now()
print(currentdate)
newsdate = "Oct-26-2021"
newsdate = datetime.datetime.strptime(newsdate, "%b-%d-%Y")
print(newsdate)
if currentdate == newsdate:
print("Extra")
else:
print("Too old")`
Compare using only the date component of datetime, accessible via the .date() attribute:
import datetime
currentdate = datetime.datetime.now()
print(currentdate)
newsdate = "Oct-26-2021"
newsdate = datetime.datetime.strptime(newsdate, "%b-%d-%Y")
print(newsdate)
if currentdate.date() == newsdate.date():
print("Extra")
else:
print("Too old")
The above can also be reworded as follows (perhaps to aid in readability for others):
from datetime import date, datetime
currentdate: date = date.today()
print(currentdate)
date_string = "Oct-26-2021"
newsdate: date = datetime.strptime(date_string, "%b-%d-%Y").date()
print(newsdate)
if currentdate == newsdate:
print("Extra")
else:
print("Too old")

upload and filter for an age based on date on mongodb python

I want to upload users date on my database, doesn't matter which format Date or String. After that I want to query for users and do $lte and $gte on all dates to find a user with specific age range (example: 25-30), but the problem that I am currently having is this:
If I make a query on users that are aged 29, and for example I have
User1: birthday: 21st May 1991
User2: birthday: 21st September 1991
and if today is for example 12th of June 2020, it gives me both users (User1 and User2), but it should give me only User1 because he has 29, and User2 is going to be 29 in a few months. Can anyone help me find a solution or propose one? Thank You!
My current Code:
ageRangeFirst = 29
ageRangeSecond = 31
current_year = int(datetime.now().year)
newFirstAge = current_year - ageRangeFirst
newSecondAge = current_year - ageRangeSecond
filter['dateOfBirth'] = {"$lte": '{}1231'.format(newFirstAge), "$gte": '{}0101'.format(newSecondAge)}
and on the database I save dates with this format as Strings:
"dateOfBirth" : "19911201" //yyyyDDmm as String
I know that my current method should give a result that I am getting but I need a little bit better date and age queriing and management.
Thank You
def addZeroToNumber(number):
if number < 10:
return '0{}'.format(number)
else:
return str(number)
def checkTheAge():
ageRangeFirst = int(request.get_json()['ageRangeFirst'])
ageRangeSecond = int(request.get_json()['ageRangeSecond'])
current_year = int(datetime.now().year)
current_month = int(datetime.now().month)
current_day = int(datetime.now().day)
print(current_year, addZeroToNumber(current_month), addZeroToNumber(current_day))
newFirstAge = current_year - ageRangeFirst
newSecondAge = current_year - ageRangeSecond - 1
date1Filter = datetime.strptime('{}-{}-{}T00:00:00.000Z'.format(newSecondAge, addZeroToNumber(current_month), addZeroToNumber(current_day)), "%Y-%m-%dT%H:%M:%S.%fZ") #19
date2Filter = datetime.strptime('{}-{}-{}T00:00:00.000Z'.format(newFirstAge, addZeroToNumber(current_month), addZeroToNumber(current_day)), "%Y-%m-%dT%H:%M:%S.%fZ") #17
print(date1Filter)
print(date2Filter)
filter['dateOfBirth'] = {"$gte": date1Filter, "$lte": date2Filter}

How to convert a string of dates to a date object?

I'm doing a chatbot to book rooms. I've created a function to check if the room asked is free while looking in the database. At some point I try to convert the entry starting and ending meeting hour to a tupple with from_pendulum_to_tupple(day_startinghour) with day_startinghour beeing for instance 2019-04-18T14:00:00+00:00
def from_pendulum_to_tupple(date):
print("date: ")
print(date)
print("type : " + str(type(date)))
year = date.year
month = date.month
day = date.day
hour = date.hour
minute = date.minute
return (year, month, day, hour, minute)
Yet I have an AttributeError: str object has no attribute year. Indeed, the error message is:
File
"C:\Users\antoi\Documents\Programming\Nathalie\18_2_2019\starter-pack-rasa-stack\actions.py",
line 43, in run
booking_answer = make_a_booking(name_room, day, hour_start, duration)
File "C:\Users\antoi\Documents\Programming\Nathalie\18_2_2019\starter-pack-rasa-stack\booking.py",
line 94, in make_a_booking
room_available = is_the_room_available(name_room, day_only, pendulum_combined_day_and_hour_start,
pendulum_combined_day_and_hour_end, cnx)
File "C:\Users\antoi\Documents\Programming\Nathalie\18_2_2019\starter-pack-rasa-stack\booking.py",
line 52, in
is_the_room_available
starting_hour_list.append(from_pendulum_to_tupple(start_time))
File "C:\Users\antoi\Documents\Programming\Nathalie\18_2_2019\starter-pack-rasa-stack\booking.py",
line 14, in
from_pendulum_to_tupple
year = date.year
AttributeError: 'str' object has no attribute 'year'
127.0.0.1 - - [2019-04-17 16:42:01] "POST /webhook HTTP/1.1" 500 412 1.050171
day_startinghour was created with make_a_booking which takes room, a day and an hour before calling for the above function to know if the room is used on the times we want to book it:
def make_a_booking(name_room, day, hour_start, duration):
print(name_room, day, hour_start, duration)
# connect to the localhost database
cnx = mysql.connector.connect(password='MySQL.2019', user="root", database="alex")
#day_only : get the parsed date
day_only = str(dateparser.parse(day).date())
# parse the hour in string inputed by the user and convert it the a pendulum object
hour_start_parsed = dateutil.parser.parse(hour_start, fuzzy_with_tokens=True)
pendulum_combined_day_and_hour_start = pendulum.parse(str(day_only) + " " + hour_start, strict=False)
# convert the duration in string inputed by the user and to seconds then in minutes
duration_in_seconds = convert_time(duration)
duration_in_minutes = duration_in_seconds / 60
# add the duration_in_minutes to the starting hour to get the hour start pendulum object
pendulum_combined_day_and_hour_end = pendulum_combined_day_and_hour_start.add(minutes = duration_in_minutes)
#print(pendulum_combined_day_and_hour_end)
# check if the room is available
room_available = is_the_room_available(name_room, day_only, pendulum_combined_day_and_hour_start, pendulum_combined_day_and_hour_end, cnx)
Using dparser:
import dateutil.parser as dparser
def from_pendulum_to_tupple(date):
print("date: {}".format(date))
date = dparser.parse(date,fuzzy=True)
year = date.year
month = date.month
day = date.day
hour = date.hour
minute = date.minute
return (year, month, day, hour, minute)
s = '2019-04-18T14:00:00+00:00'
print(from_pendulum_to_tupple(s))
OUTPUT:
date: 2019-04-18T14:00:00+00:00
(2019, 4, 18, 14, 0)

Categories