I want to adapt the code here: Given a date range how can we break it up into N contiguous sub-intervals? to split a range of dates as follows:
Starting date is '2015-03-20' and end date is '2017-03-12'. I want to split it into 3 parts. One for each of the 3 years, so that I get a list like this:
[['2015-03-20', '2015-12-31'], ['2016-01-01', '2016-12-31'], ['2017-01-01', '2017-03-12']]
Any pythonic way to do this?
If I don't misunderstand your meaning, you can just get the middle years and append it to the string like -12-31 or -01-01.
start_date = '2015-03-20'
end_date = '2018-03-12'
def split_date(s,e):
return [[s,s[:4]+"-12-31"]]+ [['%s-01-01'%(str(i)), '%s-12-31'%(str(i))] for i in range(int(s[:4])+1,int(e[:4]))]+[[e[:4] + "-01-01", e]]
print(split_date(start_date,end_date))
Result:
[['2015-03-20', '2015-12-31'], ['2016-01-01', '2016-12-31'], ['2017-01-01', '2017-12-31'], ['2018-01-01', '2018-03-12']]
Modifying the original code that you linked:
from datetime import datetime, timedelta
def date_range(start, end, interval):
start = datetime.strptime(start, "%Y%m%d")
end = datetime.strptime(end, "%Y%m%d")
diff = (end - start) / interval
for i in range(interval):
if i == 0:
date_additive = 0
else:
date_additive = 1
yield ["{0}-{1}-{2}".format(str(((start + diff * i) + timedelta(days=date_additive)).strftime("%Y").zfill(2)),
str(((start + diff * i) + timedelta(days=date_additive)).strftime("%m").zfill(2)),
str(((start + diff * i) + timedelta(days=date_additive)).strftime("%d").zfill(2))),
"{0}-{1}-{2}".format(str((start + diff * (i + 1)).strftime("%Y").zfill(2)),
str((start + diff * (i + 1)).strftime("%m").zfill(2)),
str((start + diff * (i + 1)).strftime("%d").zfill(2)))]
Input example:
def main():
begin = "20150320"
end = "20170312"
interval = 3
print(list(date_range(begin, end, interval)))
main()
Results:
[['2015-03-20', '2015-11-16'], ['2015-11-17', '2016-07-14'], ['2016-07-15', '2017-03-12']]
Related
how to calculate based on timestamp and get the progress before the max full value?
def full_energy():
time_now = 1666650096 #changes every update
time_end = 1666679529
max_energy = 50
diff = datetime.utcfromtimestamp(time_now) - datetime.utcfromtimestamp(time_end)
secs = diff.total_seconds()
???
# expected output
# x/y (z)
# 25/50 (50%)
how to get the value of x and z based on this sample?
Something like this will work. You need to provide the start time to compute percent completed. Not sure how you want the display to function:
from datetime import datetime, timedelta
import time
def full_energy(start, now, end):
max_energy = 50
percent = (now - start) / (end - start)
current_energy = max_energy * percent
# In a typical text console this will overwrite the same line
print(f'\r{current_energy:.0f}/{max_energy} ({percent:.0%})', end='', flush=True)
start = datetime.now()
end = start + timedelta(seconds=10)
while (now := datetime.now()) <= end:
time.sleep(.2)
full_energy(start, now, end)
I am trying to use list comprehension and the power of the nested function to return a list of all Dates being Friday 13 within a given year in the form (dd/mm/yyyy). I am however having very little luck with nested loops, I would appreciate any assistance I could get with resolving this issue.
The previously created function to be used is seen as:
def day_of_week11(d, m, y):
# Write your code here
day_names =['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
if m < 3:
y -= 1
m += 12
m -= 2
yd = y % 100
yc = y // 100
day = (d + ((13*m-1)//5) + yd + yd//4 + yc//4 - 2*yc) % 7
day=(math.ceil(day))
if 2>day>=1:
return day_names[0]
elif 3>day>=2:
return day_names[1]
elif 4>day>=3:
return day_names[2]
elif 5>day>=4:
return day_names[3]
elif 6>day>=5:
return day_names[4]
elif 7>day>=6:
return day_names[5]
else:
return day_names[6]
#The function I am attempting to write now is:
def not_lucky (yr):
def day_of_week11(d, m, y):
# Write your code here
i=(d, m, y)
return len([i for i in range(12) if day_of_week11(d, m, y)(yr,i+1,13)==4])
from datetime import timedelta, date
given_year=2021
start_date = date(given_year, 1, 1)
end_date = date(given_year+1, 1, 1)
list_of_friday_the_thirteenth=[single_date.strftime("%d/%m/%Y") for single_date in (start_date + timedelta(n) for n in range((end_date-start_date).days)) if single_date.weekday()==4 and single_date.day==13 ]
print(list_of_friday_the_thirteenth)
List comprehension would be too complicated in this case.
Possible solution is following:
from datetime import date, timedelta
def thirteenth_fridays(year):
d = date(year, 1, 1)
if d.weekday() <= 4:
days = 4 - d.weekday()
else:
days = 11 - d.weekday()
d += timedelta(days)
while d.year == year:
if d.day == 13:
yield d.strftime("%d/%m/%Y")
d += timedelta(days = 7)
for d in thirteenth_fridays(2024):
print(d)
Prints
13/09/2024
13/12/2024
i have start date and end date and dataframe with daily observations. The problem is that i can't find a way, which will enable me select dates with periodicity of 3 months
for example:
2003-01-03 + 3 months = 2003-04-03 and so on
output should consist of 20 rows because 5 years with 3 months periodicity, including start and end dates
EDIT: Old solution didn't work for all cases. Therefore a new one:
start, end = returns.index[0], returns.index[-1]
length = (end.year - start.year) * 12 + (end.month - start.month)
if length % 3 == 0 and end.day >= start.day:
length += 3
new_index = []
for m in range(3, length, 3):
ydelta, month = divmod(start.month + m, 12)
day = pd.Timestamp(year=start.year + ydelta, month=month, day=1)
day += pd.Timedelta(f'{min(start.day, day.days_in_month) - 1}d')
new_index.append(day)
new_index = pd.DatetimeIndex(new_index)
returns = returns.loc[new_index]
Another version which has some slight inaccuracies around the month ends but is more compact:
add_3_months = pd.tseries.offsets.DateOffset(months=3)
new_index = pd.date_range(returns.index[0] + add_3_months,
returns.index[-1],
freq=add_3_months)
returns = returns.loc[new_index]
I am very new to Python and we were told to write the weekday function without any modules like e.g. daytime etc.
But it doesn't work and i am not sure where is a problem
def weekDay (day,month,year):
global y0
global m0
global x
y0 = 0
m0 = 0
day,month,year = int(input("Enter a day: "))
month = int(input("Enter a month: "))
year = int(input("Enter a year:"))
a = (day + x + (31 * m0) // 12) % 7
for m0 in a:
m0 = month + 12 * ((14 - month) // 12) - 2
for x in a:
x = y0 + y0 // 4 - y0 // 100 + y0 // 400
for y0 in x:
y0 = year - ((14 - month) // 12)
if a == 0:
print("Sunday")
elif a == 1:
print("Monday")
elif a == 2:
print("Tuesday")
elif a == 3:
print("Wednesday")
elif a == 4:
print("Thursday")
elif a == 5:
print("Friday")
else:
print("Error")
return weekDay(a)
'''
here is the formula we were given:
[![formula][1]][1]
[1]: https://i.stack.imgur.com/iBv30.png
This should help:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.strftime('%A')
'Friday'
>>>
Global variables not defined anywhere and I am not able to understand the logic you are trying to write. So written a function based on a aptitude trick.
def weekday(day,month,year):
"""
This function is written based upon aptitude trick
to obtain day from given a date.
Input date example : 15-5-2020
Link for logic : https://www.youtube.com/watch?v=rJ0_GWDTdD4
"""
# for different months we are assigning specific number to that month
months = {1:1, 2:4, 3:4, 4:0, 5:2, 6:5, 7:0, 8:3, 9:6, 10:1, 11:4, 12:6}
# assigning days to a number
day_name = {1:'Sunday', 2:'Monday', 3:'Tuesday', 4:'Wednesday', 5:'Thursday',
6:'Friday', 0:'Saturday'}
# to get the year in between 1600 and 2000. since we are assiging values
# for the years also
while year not in range(1600,2000):
if year>2000:
year-=400
if year<1600:
year+=400
# assigning values to years
if year in range(1600,1700):
yr = 6
if year in range(1700,1800):
yr = 4
if year in range(1800,1900):
yr = 2
if year in range(1900,2000):
yr = 0
# assigning last two numbers of year to last
first = year//100
last = year - (first * 100)
# obtaining remainder
res = (day + months[month] + yr + last + (last//4))%7
#returning the day_name
return day_name[res]
day,month,year = list(map(int,input("Enter date in format dd-mm-yyyy : ").split('-')))
print(weekday(day,month,year))
Hope, you are satisfied with logic.
How do I get the start date and end date of the week, given week number and year in python?
I've tried this:
def get_start_end_dates(year, week):
dlt = timedelta(days = (week - 1) * 7)
d = date(year, 1, 1)
return d + dlt, d + dlt + timedelta(days=6)
But with this function I assume that first week of the year starts with Monday.
I have fixed your function:
def get_start_end_dates(year, week):
d = date(year,1,1)
if(d.weekday()<= 3):
d = d - timedelta(d.weekday())
else:
d = d + timedelta(7-d.weekday())
dlt = timedelta(days = (week-1)*7)
return d + dlt, d + dlt + timedelta(days=6)
It gets the correct start and end day of the week in given year.
It also assumes that years with first day of the year on Friday, Saturday or Sunday have 1 week on next week. See here: http://en.wikipedia.org/wiki/Week
Simplest (alternative) solution
First install the isoweek package
pip install isoweek
from isoweek import Week
w = Week(2021, 1)
print ("Week %s starts on %s" % (w, w.monday()))
print ("Week %s ends on %s" % (w, w.sunday()))
Output:
Week 2021W01 starts on 2021-01-04
Week 2021W01 ends on 2021-01-10
Bonus:
If you need to apply this function to pandas dataframe
df["start_of_wk"] = df.apply(lambda x: Week(x['Year'], x['wk_of_the_year']).monday(), axis=1)
df["end_of_wk"] = df.apply(lambda x: Week(x['Year'], x['wk_of_the_year']).sunday(), axis=1)
import datetime
import time
def getDateRangeFromWeek(p_year,p_week):
firstdayofweek = datetime.datetime.strptime(f'{p_year}-W{int(p_week )- 1}-1', "%Y-W%W-%w").date()
lastdayofweek = firstdayofweek + datetime.timedelta(days=6.9)
return firstdayofweek, lastdayofweek
#Call function to get dates range
firstdate, lastdate = getDateRangeFromWeek('2019','2')
print('print function ',firstdate,' ', lastdate)