Calendar algorithms - python

I am doing task for my classes. I've got one where I need to show how many day of week (Mondays, Tuesday, Wednesday, Thursday etc.) are in specific month. For an example: March 2017 had 4 mon, 4 tue, 5 wed, 5 th, 5 fri, 4 sat, 4 sun.
So far I did...
class Calendar():
def __init__(self, month, year):
self.month = month
self.year = year
if month < 1 or month > 12:
print("Error 404 month not found")
def show(self):
print(Calendar) ##Just test
test1 = Calendar(0, 2017)
test1.show()
and I'm stuck, because I don't really know how can I find particular day in month using month and year.

I don't think you should use libraries - clearly the task is to come up with algorithm and not to use existing tools. I'm not going to write a code as this is your assignment. But I'll try to help with the approach:
Try defining a single known date that you know is Monday.
Define a single year that you know is a leap year
Define a months list that stores the numbers of days in each month
For any input month and year calculate a number of days from your know date to the first day of the month.
Use modulo 7 operation on the result of step 4 to find the day of the week for the first day in month
Now subtract the number of days in given month (but also check here for leap years) from the first ocurrence of given day of the week and use some more modulo 7 arithmetics to find out the number of particular days of the week in a given month.

Related

How to get date range for a specific month starting with a previous month using Pandas

I'm trying to build a list of "pay days" for a given month in the future knowing only when the pay days started months ago. For example:
Starting date - When the paychecks started: 1/6/2023
Frequency is every two weeks
So if I want to know which dates are pay days in March, I have to start at the 1/6/2023 and add two weeks until I get to March to know that the first pay day in March is 3/3/2/2023.
Then I want my final list of dates to be only those March dates of:
(3/3/2023, 3/17/2023, 3/31/2023)
I know I can use pandas to do something like:
pd.date_range(starting_date, starting_date+relativedelta(months=1), freq='14d')
but it would include every date back to 1/6/2023.
The easiest thing to do here would be to just update the starting_date parameter to be the first pay day in the month you're interested in.
To do this, you can use this function that finds the first pay day in a given month by first finding the difference between your start date and the desired month.
# month is the number of the month (1-12)
def get_first_pay_day_in_month(month=datetime.datetime.now().month,
year=datetime.datetime.now().year,
start_date=datetime.datetime(2023, 1, 6),
):
diff = datetime.datetime(year, month, 1) - start_date
freq = 14
if diff.days % freq == 0:
print(f'Difference: {diff.days/freq} weeks')
return datetime.datetime(year,month,1)
else:
print(f'Difference: {diff.days} days')
print(f'Days: {diff.days % freq} extra')
return datetime.datetime(year,month,1 + 14 - (diff.days % freq))
Then you can use this function to get the first pay day of a specific month and plug it into the date_range method.
from dateutil import relativedelta
starting_date = get_first_pay_day_in_month(month=3)
pay_days = pd.date_range(starting_date, starting_date+relativedelta.relativedelta(months=1), freq='14d')
print(pay_days)

Get week of UK fiscal year

I want to get the week number corresponding to the UK fiscal year (which runs 6th April to 5th April). report_date.strftime('%V') will give me the week number corresponding to the calendar year (1st January to 31st December).
For example, today is 2nd February which is UK fiscal week 44, but %V would return 05.
I've seen the https://pypi.org/project/fiscalyear/ library but it doesn't seem to offer a way to do this. I know that I can work out the number of days since April 6th and divide by 7, but just curious if there's a better way.
This does the job in Python. It counts the number of days since April 6th of the given year (formatted_report_date), and if the answer is negative (because April 6th hasn't passed yet), then a year is subtracted. Then divide by 7 and add 1 (for 1-indexing). The answer will be between 1-53.
def get_fiscal_week(formatted_report_date):
"""
Given a date, returns the week number (from 1-53) since the last April 6th.
:param formatted_report_date: the formatted date to be converted into a
fiscal week.
"""
from datetime import datetime
fiscal_start = formatted_report_date.replace(month=4, day=6)
days_since_fiscal_start = (formatted_report_date - fiscal_start).days
if days_since_fiscal_start < 0:
fiscal_start = fiscal_start.replace(year=fiscal_start.year-1)
days_since_fiscal_start = (formatted_report_date - fiscal_start).days
return (days_since_fiscal_start / 7) + 1

Calculate first day of the week, given year and week number of the year

In python, How can we calculate the first day of the week when given a year and the particular week number of the year?
Note that date should be in format YYYY-MM-DD. Year and the week number is given in int format..
I am making the following assumptions about what your question means. If they are off, it should not be hard to adjust the code.
1) The first day of the week is Sunday. (so the answer is always a Sunday)
2) The week in which January 1 falls is week 1 (not 0).
Then the work breaks down into two parts.
a) Figure out the first day of the first week.
b) Add the right number of days onto that.
In Python, it looks as follows:
import datetime
def firstDayOfWeek1(y):
#takes a year and says the date of the first Sunday in the week in which January 1 falls
janDay = datetime.date(y,1,1)
while (janDay.weekday()!=6):#back up until Sunday, change if you hold Sunday is not the first day of the week
janDay=janDay-datetime.timedelta(days=1)
return janDay
def firstDayOfWeekN(y, n):#takes a year and a week number and gives the date of the first Sunday that week
return firstDayOfWeek1(y)+datetime.timedelta(weeks=(n-1))
def formattedFirstDayOfWeekN(y, n):#takes a year and a week number and gives the date of the first Sunday that week
return firstDayOfWeekN(y, n).isoformat()
#example
print formattedFirstDayOfWeekN(2018,2)#2018-01-07, first day of second week of January this year
I am using an algorithm which starts with a close-by date and then simply loops down till it finds the desired result. I am sacrificing some CPU cycles for ease of readability since the cost is not significant. I have done some limited testing but I hope the general idea is clear. Let me know your thoughts.
#This is the input in integer format
input_year = 2018
input_week = 29
#The general idea is that we will go down day by day from a reference date
#till we get the desired result.
#The loop is not computationally intensive since it will
#loop at max around 365 times.
#The program uses Python's ISO standard functions which considers Monday as
#the start of week.
ref_date = date(input_year+1,1,7) #approximation for starting point
#Reasoning behind arguments: Move to next year, January. Using 7 as day
#ensures that the calendar year has moved to the next year
#because as per ISO standard the first week starts in the week with Thursday
isoyear,isoweek,isoday = ref_date.isocalendar()
output_date = ref_date #initialize for loop
while True:
outisoyear,outisoweek,outisoday = output_date.isocalendar()
if outisoyear == input_year and outisoweek == input_week and outisoday == 1:
break
output_date = output_date + timedelta(days=-1)
print(output_date)

How to determine the date of Starting day of current and last week in python ?

I need to find the date of the starter day of current and last week.
Here, business day of a week starts from SUNDAY. So, for today the date I want is to be "07-16-2017" as "mm--dd--yyyy" format. I can get today's date easily from datetime.datetime.now().strftime ("%Y-%m-%d") but from the sysdate I have to pull out the starter day of the week.
I need the starter day's date for last week as well.
There is no default method for week information in datetime. Is there any other method in any package in python to determine the required information ?
You can use calendar.firstweekday() to check what the first day of the week is on that computer (0 is Monday, 6 is Sunday).
1) Let's say that firstweekday returned 1 (Sunday). Then you can use
date.today() - datetime.timedelta(days=date.today().isoweekday() % 7)
to compute the date of the last Sunday.
2) Let's say that firstweekday returned 0 (Monday).
date.today() - datetime.timedelta(days=date.today().isoweekday() % 7 - 1)
to compute the date of the last Monday.
Hope this gives you some direction.

Algorithm for getting current week number after changing the starting day of the week in python?

I want to design an algorithm which will calculate the week number according to the start week day set. for eg : - If I set the start day as WEDNESDAY and currently its 40 week and its TUESDAY, it should print 40 as the week number. If it is WEDNESDAY or THURSDAY, I should get 41.
Think of it like a cycle. From Wednesday till tuesday, it should be assigned a week no + 1, then when next wednesday comes, week should be incremented again.
I tried using calendar.setfirstweekday(calendar.WEDNESDAY) and then altering my system machine time, all I get is 40 as the week number everytime.
How do I design such as algorithm in python?
I have a similar problem for month, but I have designed a solution for it. Here is it.
current_date = datetime.datetime.now()
if current_date.day < gv.month_start_date:
month = current_date.month -1
if month == 0:
month = 12
else:
month = current_date.month
How can I design it for week?
I finally designed a solution for this.
if current_day >= set_week_day:
week = current_week
else:
week = current_week - 1
Works for all cases.
datetime in python has a function called isocalender to get the ISO week number (starts on Monday)
import datetime
datetime.date(2013, 9, 30).isocalendar()[1]
You can use this with a little bit of logic (this script should have the week begin on Wednesdays)
import datetime
day = 30
month = 9
year = 2013
weekcount = datetime.date(year, month, day).isocalendar()[1]
if datetime.date(year, month, day).isocalendar()[2] <= 3: # start on wednesday
weekcount -= 1
print weekcount

Categories

Resources