I'm building an API for my college's timetable website. The default option is to look up today's timetable. However, the timetable system is using week numbering different to the one we normally use.
One of the 2 things I need to build the URL is the week number.
TIMETABLE_URL = 'http://timetable.ait.ie/reporting/textspreadsheet;student+set;id;{}?t=student+set+textspreadsheet&days=1-5&=&periods=3-20&=student+set+textspreadsheet&weeks={}&template=student+set+textspreadsheet'
Week numbering should start at this date: 27 Aug 2018 - 2 Sep 2018. Following this, week 2 would be 3 Sep 2018-9 Sep 2018 and so on. This should carry over New Years, the date of 31 Dec 2018-6 Jan 2019 would be week 19. This 'year' would have 52 weeks total.
I know how to check if a certain date is in between one of the ranges from above, but I want to avoid manually setting all the date ranges. How can I have a script know that, for example, it's in week 3 on 12 September?
Using datetime.datetime object:
from datetime import datetime
start = datetime.strptime('20180827', '%Y%m%d')
current = datetime.strptime('20180912', '%Y%m%d')
print((current - start).days//7 +1) # The week number
# Output: 3
This can also handle different years. Note that this only works when the start date is Monday.
Related
I need a function to count the total number of days in the 'days' column between a start date of 1st Jan 1995 and an end date of 31st Dec 2019 in a dataframe taking Leapyears into account as well
For example:
1st Jan 1995 - Day 1
1st Feb 1995 - Day 32
2nd Feb 1995 - Day 33...
And so on all the way to 31st Dec 2019.
This is the function I created initially but it doesn't work.
prices is the name of the data frame and 'days' is the column where the number of days is to reflect.
def date_difference(self):
for i in range(prices.shape[0] - 1):
prices['days'][i+1] = (prices['days'][i+1] - prices['days'][i])
Convert types
First of all, make sure that the days column is the proper type. Use df.days.dtype and it should be datetime64. If you get object type that means you have a string containing a date and you need to convert the type using
df.days = pd.to_datetime(df.days)
Calculate difference
df['days_diff'] = (df.days - pd.Timestamp('1995-01-01')).dt.days
Also, I would recommend changing the name of the column to date before it contains dates. Later you can assign the days to a column called so. It's just for clarity of your code and future maintaining it.
I finally got it to work by doing this:
def date_difference(last_day):
last_day = pd.to_datetime(last_day, dayfirst = True)
first_day = pd.to_datetime("01/01/1995", dayfirst = True)
diff = last_day - first_day
prices['days'] = prices['days'].apply(date_difference)
I'm running Python 3.8.3 and I found something weird about the ISO Week format (%V) :
The first day and the last day of 2019 are both in week 1.
from datetime import date
print(date(2019, 1, 1).strftime('%Y-W%V'))
print(date(2019, 12, 29).strftime('%Y-W%V'))
print(date(2019, 12, 31).strftime('%Y-W%V'))
Output:
2019-W01
2019-W52
2019-W01
Why does it behave like that?
It is fully correct.
As you see in your dates, all of them are in 2019, so it is correct to get 2019 with %Y.
Week number is defined by ISO, and so one week could be considered in previous or in next year.
You need to use %G to get year of the week number (%V).
I'm trying to generate week number string using Python time module, considering week starts on Sunday.
If my interpretation of the official documentation is correct then this can be achieved by the following code:
import time
time.strftime("%U", time.localtime())
>> 37
My question is, is the above output correct? Shouldn't the output be 38 instead, considering the below details:
My timezone is IST (GMT+5:30)
import time
#Year
time.localtime()[0]
>> 2019
#Month
time.localtime()[1]
>> 9
#Day
time.localtime()[2]
>> 18
Yes, the output is correct. Week 1 started on January 6th, as that was the first Sunday in 2019. January 1st through 5th were week 0:
>>> time.strftime('%U', time.strptime("2019-1-1", "%Y-%m-%d"))
'00'
>>> time.strftime('%U', time.strptime("2019-1-6", "%Y-%m-%d"))
'01'
This is covered in the documentation:
All days in a new year preceding the first Sunday are considered to be in week 0.
You are perhaps looking for the ISO week date, but note that in this system the first day of the week is a Monday.
You can get the week number using that system with the datetime.date.isocalendar() method, or by formatting with %V:
>>> time.strftime("%V", time.localtime())
'38'
>>> from datetime import date
>>> date.today().isocalendar() # returns ISO year, week, and weekday
(2019, 38, 2)
>>> date.today().strftime("%V")
'38'
It's correct since you start counting from the first Sunday.
%U - week number of the current year, starting with the first Sunday as the first day of the first week
https://www.tutorialspoint.com/python/time_strftime.htm
It's correct. Since all days in a new year preceding the first Sunday are considered to be in week 0 (01/01 to 01/05), this week is the week 37.
I have a requirement to run a report on a weekly basis with week starting from Saturday and ending on Friday. However since the datetime or calendar module has week starting from Monday i couldn't use WEEKDAY option.
I tried the below option however it still gives me 5 for saturday,is there any options available to set weekstart day to Saturday so that for saturday it is 0 ? so that i can minus it from current date to get the desired dates or any other solution to acheive the same
Eg) If i run the report on August 30th it should fetch the data for August 18 to August 24
import calendar
calendar.setfirstweekday(calendar.SATURDAY)
calendar.firstweekday()
5
Thanks to the post Python: give start and end of week data from a given date slightly modified it based on my needs
dt = datetime.now()
start = (dt - timedelta(days = (dt.weekday() + 2) % 7)) - timedelta(days=7)
end = (start + timedelta(days=6))
print(start.strftime("%Y-%m-%d"))
print(end.strftime("%Y-%m-%d"))
It gives you 5 for Saturday, because 0 is Monday.
>>> calendar.setfirstweekday(calendar.MONDAY)
>>> calendar.firstweekday()
0
Date is datetime.date(2013, 12, 30)
I am trying to get week number using
import datetime
datetime.date(2013, 12, 30).isocalendar()[1]
I am getting output as ,
1
Why i am not getting week number of last year , instead i am getting week number of current year?
Whats wrong i am doing here ?
You are doing nothing wrong, 2013/12/30 falls in week 1 of 2014, according to the ISO8601 week numbering standard:
The ISO 8601 definition for week 01 is the week with the year's first Thursday in it.
The Thursday in that week is 2014/01/02.
Other ways to explain the definition, from the same linked WikiPedia article:
It is the first week with a majority (four or more) of its days in January (ISO weeks start on Monday)
Its first day is the Monday nearest to 1 January.
It has 4 January in it. Hence the earliest possible dates are 29 December through 4 January, the latest 4 through 10 January.
It has the year's first working day in it, if Saturdays, Sundays and 1 January are not working days.
If you were looking for the last week number of a given year (52 or 53, depending on the year), I'd use December 28th, which is always guaranteed to be in the last week (because January 4th is always part of the first week of the next year):
def lastweeknumber(year):
return datetime.date(year, 12, 28).isocalendar()[1]
from datetime import date
from datetime import datetime
ndate='10/1/2016'
ndate = datetime.strptime(ndate, '%m/%d/%Y').strftime('%Y,%m,%d')
print('new format:',ndate)
d=ndate.split(',')
wkno = date(int(d[0]),int(d[1]),int(d[2])).isocalendar()[1]
print(wkno)
manually or read a date to a string and get the week number, play around with different formats.