Python - count the number of sundays on the first day of month between two dates - python-3.x

I need to calculate the number of sundays by importing calendar, but I don't have a clue on how to determine if those sundays are on the first day of the month. Any guide please?

Use the standard datetime module. Here is a very simple naive algorithm to approach your problem:
1) Get the starting and ending dates to look between them
2) Iterate on all dates between the given two (using the date's ordinal)
3) Check whether or not it is Sunday first usind date.day and date.weekday
from datetime import date
date1 = date(2005, 1, 1)
date2 = date(2008, 1, 1)
date1_ord = date1.toordinal()
date2_ord = date2.toordinal()
cnt = 0
for d_ord in range(date1_ord, date2_ord):
d = date.fromordinal(d_ord)
if (d.weekday() == 6) and (d.day == 1):
cnt = cnt + 1
print("Number of Sunday 1'st days is {}".format(cnt))

Related

Find End Date If We Have Start Date and Interval . Excluding custom holiday list and weekends . In Python(Django)

So, What I am trying to achieve is.
start_date = "2020-07-16"
number_of_days = 15
holidays = ["2020-07-19",2020-07-21]
Now I Want to calculate the end date i.e 16 Aug + 15 days excluding all custom holidays which I give in the list and all the weekend's(Sundays+Saturdays).
Any suggestions on how could I achieve it. The solution I found till now is this using NumPy but it doesn't fulfill my requirements.
total_days = number_of_days
for i in number_of_days:
current_day = start_data + timedelta(days=i)
if current_day in holidays:
total_days += 1
elif current_day.isoweekday() in [6, 7]:
total_days += 1
end_date = start_date + timedelta(days= total_days)
I hope that this can at least get close to the answer you want, Im not sure aboyt the exact syntax as I am currently on a phone.
But looking at the NumPy answer, what exactly doesn't it fill in your requirements?

Pandas to recognize current date, and filter a date column relative to today's date

Having a lot of trouble translating the logic below in pandas/python, so I do not even have sample code or a df to work with :x
I run a daily report, that essentially filters for data from Monday thru the day before what 'Today' is. I have a Date column [ in dt.strftime('%#m/%#d/%Y') format] . It will never be longer than a Monday-Sunday scope.
1) Recognize the day it is 'today' when running the report, and recognize what day the closet Monday prior was. Filter the "Date" Column for the Monday-day before today's date [ in dt.strftime('%#m/%#d/%Y') format ]
2) Once the df is filtered for that, take this group of rows that have dates in the logic above, have it check for dates in a new column "Date2". If any dates are before the Monday Date, in Date2, change all of those earlier dates in 'Date2' to the Monday date it the 'Date' column.
3) If 'Today' is a Monday, then filter the scope from the Prior Monday through - Sunday in the "Date" Column. While this is filtered, do the step above [step 2] but also, for any dates in the "Date2" column that are Saturday and Sunday Dates - changes those to the Friday date.
Does this make sense?
Here're the steps:
from datetime import datetime
today = pd.to_datetime(datetime.now().date())
day_of_week = today.dayofweek
last_monday = today - pd.to_timedelta(day_of_week, unit='d')
# if today is Monday, we need to step back another week
if day_of_week == 0:
last_monday -= pd.to_timedelta(7, unit='d')
# filter for last Monday
last_monday_flags = (df.Date == last_mon)
# filter for Date2 < last Monday
date2_flags = (df.Date2 < last_monday)
# update where both flags are true
flags = last_monday_flags & date2_flags
df.loc[flags, 'Date2'] = last_monday
# if today is Monday
if day_of_week == 0:
last_sunday = last_monday + pd.to_timedelta(6, unit='d')
last_sat = last_sunday - pd.to_timedelta(1, unit='d')
last_week_flags = (df.Date >= last_monday) & (df.Date <= next_sunday)
last_sat_flags = (df.Date2 == last_sat)
last_sun_flags = (df.Date2 == last_sun)
# I'm just too lazy and not sure how Sat and Sun relates to Fri
# but i guess just subtract 1 day or 2 depending on which day
...

Selecting data from a range in VBA

first of all thanks for your time. I have an excel file with a matrix similar to this:
And I have a function in VBA that, for a given date c, it select the previous date and the posterior date. That is the function:
Function Dates(ByVal date, matrix) As Double
If TypeName(matrix) = "Range" Then matrix = matrix
nCols = UBound(matrix, 2)
If date > matrix(1, nCols) Then date = matrix(1, nCols)
If date < matrix(1, 1) Then date = matrix(1, 1)
date1 = 1
While date > matrix(1, date1) And date1 <= nCols
date1 = date1 + 1
Wend
date1 = date1 - 1
If date1 = 1 Then date1 = 2
If date1 >= nCols Then date1 = nCols - 1
date2 = date1 + 1
End Function
I think that is correct. The value date is the date which it will be used to obtain the previous date and the posterior date of that date. and matrix is the matrix of the picture, but what I need is that when the previous and the posterior dates are selected (date1 and date2), the values of each date, I need them to do some operation. Something like this:
For a date date = 26/9/2016, the previous date (date1) is 29/07/2016 and the posterior date (date2) is 29/10/2016. What I want to obtain is:
29/07/2016 29/07/2016
15,58% 15,58%
8,21% 8,21%
5,65% 5,65%
. .
. .
. .
1,39% 1,46%
And then, be able to do a loop through those column to perform an interpolation to obtain the values for the date.
Is possible to do that? If you can help me I would appreciate it
Thank you so much for taking your time to read and trying to help.

Get day number within calendar week for a specific date

I have a data set which includes dates.
I need to split this out by week number for reporting purposes.
What I have so far is:
startDate variable containing 03/01/2015 (populated from data in spreadsheet)
startDay = Day(startDate)
startMonth = Month(startDate)
startYear = Year(startDate)
startWeek = Application.WorksheetFunction.WeekNum(DateSerial(startYear, startMonth, startDay))
which gives me week 1 in startWeek
However I know need to know how far into week 1 the date is.
So for this example, as the date is the 3rd of January, it includes 3 days of week 1
Meaning the reporting I'm putting together will only report on 3 days (as opposed to the full week)
The only way I've figured to do this so far is to calculate which day of the year the date is and the use a MOD calculation (basically divide by 7 and the remainder is how far into the week it is)
dayNumber = DateDiff("d", DateSerial(startYear, 1, 1), DateSerial(startYear, startMonth, startDay)) + 1
dayOfWeek = dayNumber Mod 7
This does work, but I was wondering if there was a nicer solution than this.
You could use a loop to determine how many days before startDate the week number changed:
Public Sub FindDaysInWeekNo()
Dim startDate As Date
startDate = DateSerial(2015, 1, 3)
Dim startWeek As Integer
startWeek = Application.WorksheetFunction.WeekNum(startDate)
Dim i As Integer
Do While startWeek = Application.WorksheetFunction.WeekNum(DateAdd("d", -i, startDate))
i = i + 1
Loop
Debug.Print i '= 3rd day in this week number
End Sub
The following table shows my comparison to the other suggested formulas and why I think that (refered to =WEEKNUM) my calculation is correct.
Note that if you assume 1st to 7th January will be week 1 (days 1 to 7) you cannot use the WeekNum function because this will give you a different result (see table above and note that the first week has only 6 days according to the WeekNum function). Also you cannot name this week number (as what everybody calls week number is defined as https://en.wikipedia.org/wiki/Week#Week_numbering).
Instead you will need to use …
Public Function AlternativeWeekNum(startDate As Date) As Integer
AlternativeWeekNum = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) \ 7 + 1 'note that this no normal division but a integer division and uses a backslash instead
End Function
to calculate the week number your alternative way, and …
Public Function AlternativeWeekNumDay(startDate As Date) As Integer
AlternativeWeekNumDay = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) Mod 7 + 1
End Function
to calculate the day in the alternative week.
You can use the Weekday() function for this:
=WEEKDAY(B4;2)
The second parameter mentions how you want your days to be counted (starting from Sunday or Monday, counting starting from 0 or from 1, ...).
dayOfWeek = (8 + Weekday(startDate) - Weekday(DateSerial(startYear, 1, 1))) mod 7
Just take the positive mod 7 of the difference between the current Day-Of-Week and the Day-Of-Week for the 1st January of whatever the year is

Week number to Month number

I have a date with this format : 14w01 (year : 2014 week number : 1)
I want to convert this date in month like this : 14m01
Is there a function which converts a week number in a month number ?
Maybe something like this (in vba, not in formula) :
Format(weekNumber, "mm")
Thank you
It depends on how the weeks are defined. One way is to say that the first day of week#1 of a year is 1 January of that year. For this definition, a typical UDF is:
Public Function MonthFromDt(s As String) As Integer
Dim yr As Integer, wk As Integer, d As Date
ary = Split(s, "w")
yr = CInt(ary(0)) + 2000
wk = ary(1)
MonthFromDt = Month(DateSerial(yr, 1, 1) + 7 * (wk - 1))
End Function
There are other definitions of week number.
The DateFormat function is quiet comfortable, however the DateValue function, which parses a date, won't probably support your week format.
I suggest a trick with DateAdd, as DateAdd can handle weeks.
First split your date in year and week number:
Dim parts
parts = Split("2014w33", "w")
Dim year
Dim week
year = CInt(parts(0))
week = CInt(parts(1))
Then, add both to a "zero-date" to add up to the final date. Note that if you give "0" as year for DateAdd, VBA compiler interprets 2000.
dim DateResult
DateResult = dateAdd("yyyy", (year - 2000), DateValue("Jan 1, 0"))
Debug.Print dateResult
DateResult = dateAdd("ww", week, dateResult)
Debug.Print dateResult
Then show the result reformatted:
Debug.Print Format(DateResult, "yyyy\mm")
This prints on my side:
01.01.2014
20.08.2014
2014m08
August 2014, there is week 33 if I look up in the calendar. Seems correct.
I found a way to do it without VBA (and only using Formulas). This assumes A1 contains the "14w01" format
=LEFT(A1,2)&"m"&TEXT(MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)),"00")
Heres a breakdown of what the code does..
LEFT(A1,2) returns "14" (year)
MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)) converts the week # to the month # and it takes in the year 20&LEFT(A1,2) as well as week # RIGHT(A1,2)
TEXT(...,"00") pads the month # with a 0 if necessary (i.e. 3 becomes 03)
Then we just combine everything together to get "14m01"

Resources