create a list of dates with a while loop python - python

I want tot create a list of dates starting from 10/09/2020 with increments of 182 days until reaching 05/03/2020.
my code is this :
start_date="10/09/2020"
last_date="05/03/2020"
start_date=datetimedatetime.strptime(date,"%d/%m/%Y").date()
last_date=datetimedatetime.strptime(date,"%d/%m/%Y").date()
dates=[]
while dates[-1] != last_date:
i=star_date+timedelta(days=182)
dates.append(i)
dates[i]=i+timedelta(days=pago_cupon)

I don't know what's your problem.
You can try this code
from datetime import date, timedelta
start_day = date(year=2020, month=9, day=10)
end_day = date(year=2021, month=3, day=5)
one_data_delta = timedelta(days=1)
res = []
while end_day != start_day:
start_day += one_data_delta
res.append(start_day)
print(res)

A few problems:
You had a spelling mistake in your for loop star_date instead of start_date.
Also, you may want to change the comparison from != to less than equals or more than equals.
I am checking against (last_date - timedelta(days=182)) so that we won't exceed the last_date.
Your original start date is after your original end date.
As an example, I have adjusted the end day to be a couple years in the future.
I'm appending the dates as text.
from datetime import datetime, timedelta
start="10/09/2020"
last="05/03/2022"
start_date=datetime.strptime(start,"%d/%m/%Y")
last_date=datetime.strptime(last,"%d/%m/%Y")
dates=[]
while start_date <= (last_date - timedelta(days=182)):
start_date += timedelta(days=182)
dates.append(start_date.strftime("%d/%m/%Y"))
# not quite sure what you are trying to do here:
#dates[i]=i+timedelta(days=pago_cupon)
print(dates)
Output:
['11/03/2021', '09/09/2021']

Related

Printing working dates between two dates but excluding every weekends

I am trying to print the working days between two dates, but excluding the latter one and the weekends, holding in there. I've tried the following code:
from datetime import timedelta, date, datetime
def print_working_dates(date1, date2):
excluded = (6,7)
for n in range(int((date2 - date1).days)+1):
if date1.isoweekday == excluded:
continue
else:
yield date1 + timedelta(n)
start_dt = datetime.now()
end_dt = datetime(2022, 4, 28)
for dt in print_working_dates(start_dt, end_dt):
print(dt.strftime("%Y-%m-%d"))
which prints every day before the last one, but it holds all weekends. Could anyone please anyone could give a piece of advice to define better this function? To my mind, the excluded object should be better detailed, but I cannot know how.
Firstly, you can check if a value is in an iterable (such as a tuple or list) using the in keyword. isoweekday is a function, so you need to call it with isoweekday(). Finally, you need to work out the new date, then check it's weekday, otherwise it just checks if the start date is a weekend for every date.
def print_working_dates(date1, date2):
excluded = (6,7)
for n in range(int((date2 - date1).days)+1):
new = date1 + timedelta(n)
if new.isoweekday() not in excluded:
yield new
I've negated the if statement with not to make it a bit more compact.
First off, you are not checking the correct time to be a weekday or not you have to check if (date1 + timedelta(n)) is a weekday, not date1
And secondly you have to you have to check if isoweekday's return value is in the excluded
Here's my solution to your code:
from datetime import timedelta, datetime
def print_working_dates(date1, date2):
excluded = (6,7)
for n in range(int((date2 - date1).days)+1):
if (date1 + timedelta(n)).isoweekday() in excluded:
continue
else:
yield date1 + timedelta(n)
start_dt = datetime.now()
end_dt = datetime(2022, 4, 28)
for dt in print_working_dates(start_dt, end_dt):
print(dt.strftime("%Y-%m-%d"))

Python: iterate per year between two dates

I'm not a Python developer but have to fix an existing code.
In this code, a method (extract) is called providing an interval of dates:
extract(start_date, end_date)
The parameters can have for exemple the values:
start_date : 2020-10-01
end_date : 2022-01-03
The problem
The issue with this call is that the extract method only support a 1 year max interval of dates. If greater, the interval must be split, for exemple as follow:
extract('2020-10-01', '2020-12-31')
extract('2021-01-01', '2021-12-31')
extract('2022-01-01', '2022-01-03')
So I'm trying to create loop where the start_date and end_date are computed dynamically. But being new to Python, I have no ideas for now how this can be done. Any help would be greatly appreciated.
EDIT
Answer to some comments here
Tried so far finding a solution starting from code like this so far:
from datetime import datetime
from dateutil import relativedelta
from datetime import datetime
from_date = datetime.strptime('2020-10-01', "%Y-%m-%d")
end_date = datetime.strptime('2022-01-03', "%Y-%m-%d")
# Get the interval between the two dates
diff = relativedelta.relativedelta(end_date, from_date)
Then I thought iterating accross the years using diff.years and adding some logic to build the start_date and end_date from there, but I thought there might be a much simplier approach.
Also saw others possibilities like here but still no final simple result found at the moment.
from_str = '2020-10-01'
end_str = '2022-01-03'
from_year = int(from_str[:4])
end_year = int(end_str[:4])
if from_year != end_year:
# from_date to end of first year
extract(from_str, f"{from_year}-12-31")
# full years
for y in range(from_year + 1, end_year):
extract(f"{y}-01-01", f"{y}-12-31")
# rest
extract(f"{end_year}-01-01", end_str)
else:
extract(from_str, end_str)
As mentioned in the comments, you can either use the datetime library or you can also use pandas if you want. The pandas version is the following (admittively not the most pretty, but it does the job):
import pandas as pd
import datetime
start = datetime.datetime(2020,10,1)
end = datetime.datetime(2022,1,3)
def extract(from_dt, to_dt):
print(f'Extracting from {from_dt} to {to_dt}')
prev_end = pd.to_datetime(start)
for next_end in pd.date_range(datetime.datetime(start.year, 12, 31), end, freq='y'):
if next_end < end:
extract(prev_end.strftime('%Y-%m-%d'), next_end.strftime('%Y-%m-%d'))
else:
extract(prev_end.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d'))
prev_end = next_end + datetime.timedelta(days=1)
if prev_end < end:
extract(prev_end.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d'))
If you need to parse the original dates from strings, check out datetime.strptime
This kind of problems are nice ones to resolve by recursion:
from datetime import datetime
start_date = '2020-10-01'
end_date = '2022-01-03'
def intervalcalc(datestart,dateend):
newdate=dateend[:4] + '-01-01'
startd = datetime.strptime(datestart, "%Y-%m-%d")
endd = datetime.strptime(newdate, "%Y-%m-%d")
if endd < startd:
print(datestart, dateend)
return True
else:
print(newdate, dateend)
previousyear=str(int(newdate[:4])-1) + '-12-31'
intervalcalc(datestart,previousyear)
intervalcalc(start_date, end_date)
output:
2022-01-01 2022-01-03
2021-01-01 2021-12-31
2020-10-01 2020-12-31
You just need to change the prints by calls to extract function.
As mentioned by #Wups the conversion to date is not really necessary, it could be an string compare as they are YYYYMMDD dates.
Also, this can be done the other way around and calculate from the start date year + '-12-31' and then compare dateend>end_date to determine the anchor for the recursion.

How to check whether a date is in the next week, python

Basically, I'm trying to check whether a date, e.g. 2021-07-08, is in the next week, or the week after that, or neither.
#I can call the start and end dates of the current week
start = tday - timedelta(days=tday.weekday())
end = start + timedelta(days=6)
print("Today: " + str(tday))
print("Start: " + str(start))
print("End: " + str(end))
# and I can get the current week number.
curr_week = datetime.date.today().strftime("%V")
print(curr_week)
Is there a better way than getting a list of dates in curr_week + 1 and then checking whether date is in in that list?
Thanks so much
GENERAL ANSWER
It is best to stick to datetime and timedelta, since this handles all edge cases like year changes, years with 53 weeks etc.
So find the number of the next week, and compare the weeknumber of the week you want to check against that.
import datetime
# Date to check in date format:
check_date = datetime.datetime.strptime("2021-09-08", "%Y-%d-%m").date()
# Current week number:
curr_week = datetime.date.today().strftime("%V")
# number of next week
next_week = (datetime.date.today()+datetime.timedelta(weeks=1)).strftime("%V")
# number of the week after that
week_after_next_week = (datetime.date.today()+datetime.timedelta(weeks=2)).strftime("%V")
# Compare week numbers of next weeks to the week number of the date to check:
if next_week == check_date.strftime("%V"):
# Date is within next week, put code here
pass
elif week_after_next_week == check_date.strftime("%V"):
# Date is the week after next week, put code here
pass
OLD ANSWER
This messes up around year changes, and modulo doesn't fix it because there are years with 53 weeks.
You can compare the week numbers by converting them to integers. You don't need to create a list of all dates within the next week.
import datetime
# Date to check in date format:
check_date = datetime.datetime.strptime("2021-07-08", "%Y-%d-%m").date()
# Current week number, make it modulo so that the last week is week 0:
curr_week = int(datetime.date.today().strftime("%V"))
# Compare week numbers:
if curr_week == (int(check_date.strftime("%V"))-1):
# Date is within next week, put code here
pass
elif curr_week == (int(check_date.strftime("%V"))-2):
# Date is the week after next week, put code here
pass
You can cast the date you want to check in datetime, and then compare the week numbers.
# date you want to check
date = datetime.datetime.strptime("2021-07-08","%Y-%m-%d")
# current date
tday = datetime.date.today()
# compare the weeks
print(date.strftime("%V"))
print(tday.strftime("%V"))
27
32
[see Alfred's answer]
You can get the week number directly as an integer integer from the IsoCalendarDate representation of each date.
from datetime import datetime
date_format = '%Y-%m-%d'
t_now = datetime.strptime('2021-08-11', date_format)
target_date = datetime.strptime('2021-08-18', date_format)
Just using datetime comparing:
from datetime import datetime, timedelta
def in_next_week(date):
""" -1: before; 0: in; 1: after next week;"""
today = datetime.today()
this_monday = today.date() - timedelta(today.weekday())
start = this_monday + timedelta(weeks=1)
end = this_monday + timedelta(weeks=2)
return -1 if date < start else 0 if date < end else 1
Test cases:
for i in range(14):
dt = datetime.today().date() + timedelta(days=i)
print(dt, in_next_week(dt))

Incrementing a date in python

In pandas I have a variable defined as
start_date = date (2020,7,1)
How do I update it to be the next day? I have a dataframe and I am filtering on individual days but I want to iterate through a full time range. I suppose I could have a for loop like so
for x < 10:
start_date = date (2020,7,x)
x +=1
But is there another way? I couldn't find any other stack exchange questions for python dates.
Assuming date is the regular python one you can add a day as follows:
from datetime import date, timedelta
start_date = date(2020, 7, 1)
next_date = start_date + timedelta(days=1)

python get day if its in a dates range

I'm trying to check if first date of the month and the last date of the month lies in a range of dates (the range is 7 days window starting from current date) . below is an example for what I'm trying to achieve:
import datetime, calendar
today = datetime.date.today()
date_list = [today + datetime.timedelta(days=x) for x in range(0, 7)]
lastDayOfMonth = today.replace(day=calendar.monthrange(today.year,today.month)[-1])
if 1 in [ date_list[i].day for i in range(0, len(date_list))]:
print "we have first day of month in range"
elif lastDayOfMonth in [ date_list[i].day for i in range(0, len(date_list))]:
print " we have last date of month in the range"
I'm wondering if there is a cleaner way for doing that? I also want to print the exact date if I find it in the list but I don't know how without expanding the for loop in the if statement and save print date_list[i] if it matches my condition. so instead of printing the message when I find the first day in the range I should print the actual date. same for last date.
Thanks in advance!
The only thing I can come up with, without having to make use of iteration is:
import datetime, calendar
today = datetime.date.today()
week_from_today = today + datetime.timedelta(days=6)
last_day_of_month = today.replace(day=calendar.monthrange(today.year,today.month)[-1])
if today.month != week_from_today.month:
print datetime.date(week_from_today.year, week_from_today.month, 1)
elif today <= last_day_of_month <= week_from_today:
print last_day_of_month
since today it's 2016-06-02 it's hard to test the code.
Try changing the variable today to another day. I used the dates 2016-05-25 and 2016-05-26 to test the code.
to set a custom date: today = datetime.date(yyyy, m, d)

Categories

Resources