total number of days from current date if we want to know like after 2 weeks, 3 months , 1 year - python-3.x

I want to know the total number of days from current date.
if given date is 2 Feb 2018. and i want to calculate number of days after 2 weeks/3 months/1 year. keeping in mind of leap year or not.
Language - python3
Is there any library in python which give me this.

The dateutil module has a way to do this very conveniently. Sample code:
import datetime
import dateutil
today = datetime.date.today()
delta = dateutil.relativedelta.relativedelta(years=1, months=3, weeks=2)
desired_date = today + delta
desired_date
Output:
datetime.date(2019, 5, 16)

Related

What is the purpose of offset in conjunction with datetime in Python 3.x?

I'm new to python and I'm looking to work with datetime. I have some files generated every Sunday and I like to move the furthest Sunday out of the current folder eg: 2020-04-12, 2020-04-19, 2020-04-26.
I have found some examples on getting a specific date from today's date and I was able to modify it a tab bit. Eg. I can go back and get last week's Sunday with a specific date:
from datetime import date
from datetime import timedelta
import datetime
today = datetime.datetime(2020,4,13)
offset = (today.weekday() + 1) % 7
sunday = today - timedelta(days=offset)
#print (offset)
print(sunday)
I am confused by the offset variable. What is (today.weekday() + 1) % 7 doing? I have read the Python doc and not quite wrapping my head around it. With +1, I get the date 2020-04-12, which is a Sunday, great. When I do -1 (the other thing is if I set it to (today.weekday() - 1) % 7), I get 2020-04-07, a Tuesday. How did it jump from Sunday the 12th to Tuesday the 7th?
Additionally, how do I get it to jump back 3 weeks? that's where I'm also stuck.
Alright, so if today's Wednesday, then today.weekday() is 2, because it starts counting from 0 on Monday. Not sure why, but that's life.
So (2 + 1) % 7) = 3. That means that 3 days ago was Sunday. Hence your code:
offset = (today.weekday() + 1) % 7 # How many days ago was sunday
sunday = today - timedelta(days=offset) # Go backwards from today that many days
You'll notice that if you subtract one instead of add one, that means we're going backwards (because we're sutracting the timedelta object) by two fewer days than before (because 2 - 1 is equivalent to (2 + 1) - 2, that is, two fewer days). If you started by going backwards enough days to get to Sunday, and now you're going backwards two fewer days, you'll end up on Tuesday, which is two days later than Sunday.
The easiest way to shift which week you're headed to is to set the weeks argument in timedelta:
n_weeks = 3
sunday = today - timedelta(days=offset, weeks=n_weeks)
that's equivalent to, but much prettier than:
sunday = today - timedelta(days=offset + n_weeks * 7)

Calculating time to earn a specific amount as interest

I cannot figure out the approach to this as the principle amount shall change after every year(if calculated annually, which shall be the easiest). Eventual goal is to calculate exact number of years, months and days to earn say 150000 as interest on a deposit of 1000000 at an interest rate of say 6.5%. I have tried but cannot seem to figure out how to increment the year/month/day in the loop. I don't mind if this is down voted because I have not posted any code(Well, they are wrong). This is not as simple as it might seem to beginners here.
It is a pure maths question. Compound interest is calculated as follows:
Ptotal = Pinitial*(1+rate/100)time
where Ptotal is the new total. rate is usually given in percentages so divide by 100; time is in years. You are interested in the difference, though, so use
interest = Pinitial*(1+rate/100)time – Pinitial
instead, which is in Python:
def compound_interest(P,rate,time):
interest = P*(1+rate/100)**time - P
return interest
A basic inversion of this to yield time, given P, r, and target instead, is
time = log((target+Pinitial)/Pinitial)/log(1+rate/100)
and this will immediately return the number of years. Converting the fraction to days is simple – an average year has 365.25 days – but for months you'll have to approximate.
At the bottom, the result is fed back into the standard compound interest formula to show it indeed returns the expected yield.
import math
def reverse_compound_interest(P,rate,target):
time = math.log((target+P)/P)/math.log(1+rate/100)
return time
timespan = reverse_compound_interest(2500000, 6.5, 400000)
print ('time in years',timespan)
years = math.floor(timespan)
months = math.floor(12*(timespan - years))
days = math.floor(365.25*(timespan - years - months/12))
print (years,'y',months,'m',days,'d')
print (compound_interest(2500000, 6.5, timespan))
will output
time in years 2.356815854829652
2 y 4 m 8 d
400000.0
Can we do better? Yes. datetime allows arbitrary numbers added to the current date, so assuming you start earning today (now), you can immediately get your date of $$$:
from datetime import datetime,timedelta
# ... original script here ...
timespan *= 31556926 # the number of seconds in a year
print ('time in seconds',timespan)
print (datetime.now() + timedelta(seconds=timespan))
which shows for me (your target date will differ):
time in years 2.356815854829652
time in seconds 74373863.52648607
2022-08-08 17:02:54.819492
You could do something like
def how_long_till_i_am_rich(investment, profit_goal, interest_rate):
profit = 0
days = 0
daily_interest = interest_rate / 100 / 365
while profit < profit_goal:
days += 1
profit += (investment + profit) * daily_interest
years = days // 365
months = days % 365 // 30
days = days - (months * 30) - (years * 365)
return years, months, days
years, months, days = how_long_till_i_am_rich(2500000, 400000, 8)
print(f"It would take {years} years, {months} months, and {days} days")
OUTPUT
It would take 1 years, 10 months, and 13 days

Python - Calculate date difference in months

I need to get the difference between the days in months and days (eg. 3months 20days).
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-06-23', "%Y-%m-%d")
date2 = datetime.strptime('2018-04-17', '%Y-%m-%d')
r = relativedelta.relativedelta(date1, date2)
print(r)
This gives me result like relativedelta(years=+1, months=+2, days=+6) whereas I need result like 14 months 6 days
Thank you
Incorporate a minor modification to get the answer.
print(r.years, 'years,', r.months,'months and', r.days, 'days')

How can I convert from a datetime to a weekday of the month constant?

What I want to do is figure out what X of the month this is, and returning the relative delta constant for it (Su Mo Tu...). I have found many examples of jumping to a specific day of the month (1). For instance today is the 3rd Tuesday of December and I can get to it by doing this: + relativedelta(month=12, day=1, weekday=TU(3))) but what I want to do is the opposite:
Put in today's date and subtract the first of the month and get something like TU(3) or if it were the 4th wednesday to get: WE(4)
My ultimate goal is to then be able to transfer this constant to a different month or timedelta object and find the equivalent 3rd Tuesday, or 4th Wednesday, etc...
This is a solution that I have come up with, maybe you'll find it less complicated.
It also seems to be about 4 times faster, which if you process a lot of dates can make a difference.
from datetime import *
from dateutil.relativedelta import *
def weekDayOfTheMonth(xdate):
daylist = [MO,TU,WE,TH,FR,SA,SU]
weekday = xdate.weekday()
firstDayOfTheMonth = datetime(xdate.year, xdate.month, 1)
interval = (weekday + 7 - firstDayOfTheMonth.weekday() ) % 7
firstOfThisWeekDay = datetime(xdate.year, xdate.month, 1 + interval)
n = ((xdate.day - firstOfThisWeekDay.day) / 7) + 1
return daylist[weekday](n)
print(weekDayOfTheMonth(datetime.today()))
print(weekDayOfTheMonth(datetime(2018,11,24)))
Basically what happens is that:
I find what day of the week is the first day of given month.
Based on that information I can easily calculate first day of any given weekday in given month.
Then I can even more easily calculate that for example 18th of December 2018 is third Tuesday of this month.
Ok I found a way using rrule to create a list of days in the month that share the current weekday up until today, then length of this list becomes the Nth. Than I use a list as a lookup table for the weekday constants. Not tested to see if this will work for every day of the month but this is a start.
from datetime import *; from dateutil.relativedelta import *
from dateutil.rrule import rrule, WEEKLY
import calendar
def dayofthemonth(xdate):
daylist = [MO,TU,WE,TH,FR,SA,SU]
thisweekday = daylist[xdate.weekday()]
thisdaylist = list(rrule(freq=WEEKLY, dtstart=xdate+relativedelta(day=1), until=xdate, byweekday=xdate.weekday()))
return thisweekday(len(thisdaylist))
print(dayofthemonth(datetime.today())) #correctly returns TU(+3) for 2018, 12, 18

Creating a daily account log from a Pandas expense file in data frame format

I have an expense file that I am trying to read in and from this file create a daily log. A small subset of the file that extends over years is shown below, for a few days in January 2015.
Date,Checking_Debit,Checking_Addition,Savings_Debit,Savings_Addition
2015-01-07,342.1,0.0,0.0,0.0
2015-01-07,981.0,0.0,0.0,0.0
2015-01-07,3185.0,0.0,0.0,0.0
2015-01-05,55.0,0.0,0.0,0.0
2015-01-05,75.0,0.0,0.0,0.0
2015-01-03,287.0,0.0,0.0,0.0
2015-01-02,64.8,0.0,0.0,0.0
2015-01-02,75.0,0.0,0.0,75.0
2015-01-02,1280.0,0.0,0.0,0.0
2015-01-02,245.0,0.0,0.0,0.0
2015-01-01,45.0,0.0,0.0,0.0
In my code I start with the variables checking_start and savings_start that contain the start values of the checking and savings account. I would like to give the code a start date and an end date and have the code iterate through each day, see if there was an expense on that day and subtract the checking and savings debits and add the checking and savings additions. If there were no expenses on that day it should keep the accounts at the same value as the previous day. In addition, I am trying to constrain myself to Pandas data frames in the implementation. So far my code looks like this.
import pandas as pd
from date time import date
check_start = 8500.0
savings_start = 4000.0
start_date = date(2017, 1, 1)
end_date = date(2017, 1, 8)
df = pd.read_csv(file_name.csv, dtype={'Date': str, 'Checking_Debit': float,
'Checking_Addition': float,
'Savings_Debit': float,
'Savings_Addition': float})
In a Pythonic format with the Pandas module, how do I walk through from the start date to the end date, one day at a time, then see if there is an expense or expenses on those date and then subtract that from the checking and savings. At the end I should have an array for the value of the checking account on each date and the same for the savings account on that day.
The result should be arrays written into another .csv file with the following format.
Date,Checking,Savings
2017-01-07,1865.1,3925.0
2017-01-06,6373.2,3925.0
2017-01-05,6373.2,3925.0
2017-01-04,6503.2,3925.0
2017-01-03,6503.2,3925.0
2017-01-02,6790.2,3925.0
2017-01-01,8455.0,4000.0
Start by reading the data that you provided and identifying the date column in data with it
import pandas as pd
df = pd.read_csv(r"dat.csv", parse_dates=[0],dtype={'Checking_Debit': float,
'Checking_Addition': float,
'Savings_Debit': float,
'Savings_Addition': float})
Set Date as index for better data manipulation.
df = df.set_index("Date")
Initialize all the variables for the loop
check_start = 8500.0
savings_start = 4000.0
start_date = pd.to_datetime('2015/1/1')
end_date = pd.to_datetime('2015/1/8')
delta = pd.Timedelta('1 days') # time that needs to be added to start date
Now group the expense data w.r.t to each date
grp_df = df.groupby('Date').sum()
Now we will do while loop for create expense report for each day
expense_report = []
while start_date<=end_date:
if start_date in df.index:
savings_start += (grp_df.loc[start_date,"Savings_Addition"]-grp_df.loc[start_date,"Savings_Debit"])
check_start += (grp_df.loc[start_date,"Checking_Addition"]-grp_df.loc[start_date,"Checking_Debit"])
expense_report.append([start_date,check_start,savings_start])
elif start_date not in df.index:
expense_report.append([start_date,check_start,savings_start])
start_date += delta
convert expense_report list to pandas Dataframe
df_exp_rpt = pd.DataFrame(expense_report,columns=["Date","Checking","Savings"])
print(df_exp_rpt)
Date Checking Savings
0 2015-01-01 8455.0 4000.0
1 2015-01-02 6790.2 4075.0
2 2015-01-03 6503.2 4075.0
3 2015-01-04 6503.2 4075.0
4 2015-01-05 6373.2 4075.0
5 2015-01-06 6373.2 4075.0
6 2015-01-07 1865.1 4075.0
7 2015-01-08 1865.1 4075.0
You can save to csv by
df_exp_rpt.to_csv("filename.csv")
Note: The saving column values are 4075 instead of 3925.0 because you have 75 value in saving_addition column in your original data

Resources