I am trying to get the weeks of the current month. I can get the number of the week in that month(current_w) but I will need to get a list in the correct order. For example, for July, it will be w = [27, 28, 29, 30] because current week is in the third order of the 4 weeks of this month. Can somebody help me on that?
import datetime
kw = datetime.datetime.today().isocalendar()[1]
weeks = [7,14,21,28]
for idx, i in enumerate(weeks):
delta = datetime.timedelta(days=i)
if (a - delta).month != a.month:
current_w = idx
You could use datetime to get both the first and the last week and then just everything in between.
import datetime
import calendar
year = datetime.datetime.now().year
month = datetime.datetime.now().month
first_week = datetime.datetime(year, month, calendar.monthrange(year, month)[0]).isocalendar()[1]
last_week = datetime.datetime(year, month, calendar.monthrange(year, month)[1]).isocalendar()[1]
print(list(range(first_week, last_week + 1)))
from datetime import datetime would save you all the datetime.datetime usage btw.
If you only want weeks that are fully included in a month, the first week will be the one that contains the 7th of that month. And the last week will one before the one that contains the 1st of next month.
That is enough to give the following function:
def weeks_in_month(month, year=None):
"""Returns the (ISO) weeks fully contained in a month.
month is an integer between 1 and 12. Year is the current year
if not given"""
if year is None:
year = datetime.date.today().year
first = datetime.date(year, month, 7).isocalendar()[1]
nextd = datetime.date(year + 1, 1, 1) if month == 12 \
else datetime.date(year, month + 1, 1)
nextw = nextd.isocalendar()[1]
return list(range(first, nextw))
Related
I have a date in the format "YYYY-MM-DD", for example "2022-03-09". It is the 68th day of the year 2022. Is there a way to get the 68th day of 2021? More generally, if I have a date in "YYYY-MM-DD" format, which is the N th day of the year, is there a quick way to calculate the N th day of the previous year?
You could do:
from datetime import datetime, timedelta
date_string = '2020-03-09'
# Parse the string to a datetime.date object
date = datetime.strptime(date_string, '%Y-%m-%d')
# Get the number N of the day in the year
N = date.timetuple().tm_yday
# Take 1st of january of last year and add N-1 days
N_last_year = (
date.replace(year=date.year-1, month=1, day=1) +
timedelta(days=N-1)
)
print(N_last_year.date())
Or, another funny solution based on leap years. It is based on the fact that the Nth day of last year is the same as this year's, except if the date is after 29th february and there is a leap year somewhere.
from datetime import datetime, timedelta
def leap(year: int) -> bool:
# Returns True if year is a leap year, False otherwise
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
date_string = '2020-03-09'
# Parse the string to a datetime.date object
date = datetime.strptime(date_string, '%Y-%m-%d')
# Get the number N of the day in the year
N = date.timetuple().tm_yday
date_last_year = date.replace(year=date.year-1)
# Do the cool thing
if date.month >= 3:
if leap(date.year):
date_last_year += timedelta(days=1)
elif leap(date.year-1):
date_last_year += timedelta(days=-1)
print(date_last_year.date())
The datetime objects will you with that (https://docs.python.org/3/library/datetime.html).
Indeed, you can compute the time lap between your date and the beginning of the year. Then you can add this difference to the beginning of the next year.
import datetime
date_string = "2022-03-09"
date_object = datetime.datetime.strptime(date_string, "%Y-%m-%d").date()
beginning_of_year = datetime.date(date_object.year, 1, 1)
time_difference = date_object - beginning_of_year
beginning_of_last_year = datetime.date(date_object.year - 1, 1, 1)
same_day_last_year = beginning_of_last_year + time_difference
print(same_day_last_year)
However, the result is disappointing, since it is in fact the same date...
I think you can do something like
from datetime import timedelta, date
year = timedelta(days=365)
today = date.fromisoformat("2022-03-09")
print(today - year)
How can I print the date of the last Tuesday of each month for next year using Python.
For example the first line outputted would be: 30/Jan/2018
I do not want to have the full name of the month only the first 3 characters!
Currently I have figured out how to get the next year:
import datetime
now = datetime.datetime.now()
next_year = now.year + 1
Can anyone please help?
The calendar module is perfect for this:
You can use calendar.month_abbr which is an array of
abbreviated months just like you want.
week is an array representing the days of the week starting at Monday so Tuesday would be week[1].
import calendar
import datetime
now = datetime.datetime.now()
next_year = now.year + 1
for month in range(1, 13):
last_tuesday = max(week[1] for week in calendar.monthcalendar(next_year, month))
print('{}/{}/{}'.format(last_tuesday, calendar.month_abbr[month], next_year))
Output:
30/Jan/2018
27/Feb/2018
27/Mar/2018
24/Apr/2018
29/May/2018
26/Jun/2018
31/Jul/2018
28/Aug/2018
25/Sep/2018
30/Oct/2018
27/Nov/2018
25/Dec/2018
I would also suggest the pandas DateOffset object LastWeekOfMonth.
Describes monthly dates in last week of month like "the last Tuesday
of each month"
from pandas.tseries.offsets import LastWeekOfMonth
def last_tues(year):
return (pd.date_range('1/1/' + str(year), periods=12, freq='M')
- LastWeekOfMonth(n=1, weekday=1)).strftime('%d/%b/%Y'))
last_tues(2018)
Out[31]:
array(['30/Jan/2018', '27/Feb/2018', '27/Mar/2018', '24/Apr/2018',
'29/May/2018', '26/Jun/2018', '26/Jun/2018', '28/Aug/2018',
'25/Sep/2018', '30/Oct/2018', '27/Nov/2018', '25/Dec/2018'],
dtype='<U11')
Getting error for December month.
ValueError: month must be in 1..12
def last_day_of_month(ds):
cur_ds = datetime.strptime(ds, '%Y-%m-%d')
next_month = datetime(year=cur_ds.year, month=cur_ds.month+1, day=1)
last_day_month = next_month - timedelta(days=1)
return datetime.strftime(last_day_month, '%Y-%m-%d')
print last_day_of_month('2016-12-01')
In line 3 month=cur_ds.month+1 you are giving 13th month which is not valid. If you want to calculate last day of a given month you could also use month range from calendar library.
>>import calendar
>>year, month = 2016, 12
>>calendar.monthrange(year, month)[1]
31
You can't make a datetime with a month of 13. So you have to find a way to fix it. A simple solution is to convert the incremented month to an extra year:
# Reduce 12 to 1, 0 and all other #s to 0, #
extrayear, month = divmod(cur_ds.month, 12)
# Add 1 or 0 to existing year, add one to month (which was reduced to 0-11)
next_month = datetime(year=cur_ds.year + extrayear, month=month + 1, day=1)
You're passing in 12 as current month, then adding one to get next_month, making it 13. Check for the 12 case and set month=1 instead.
this is how I did it.
from django.utils import timezone
from calendar import monthrange
from datetime import datetime
current = timezone.now()
firstdayofmonth = current.replace(day=1)
endmonth = monthrange(current.year, current.month)
lastdayofmonth = datetime(current.year, current.month, endmonth[1])
I have run into a problem with some code I have been writing. I take in four inputs ( day, month and year ) as a date, and times for how many times they want to repeat the task ( eg. every Monday for 3 weeks ). The code is great however if the weeks differ between months I get this error:
File "C:\Users\dansi\AppData\Local\Programs\Python\Python36-32\gui test 3.py", line 72, in addtimeslot
fulldateadd = datetime.date(year, month, day)
ValueError: day is out of range for month
Part of code that is relevant:
for i in range(0 , times):
fulldateadd = datetime.date(year, month, day)
cursor.execute( '''INSERT INTO dates (Date, Name, Start, End) VALUES( ?,?,?,? );''', (fulldateadd , name1, starttimehour, endtimehour))
day = day + 7
if day > 31:
month = month + 1
I've tried to increment the month when the number of days are more than 31 however it doesn't seem to work.
There are several reasons why incrementing the components of a datetime and then creating a new one is not a good idea. Primarily because dealing with the Gregorian calendar yourself isn't that enjoyable IMHO, and datetime objects can do it for you.
On that note, a much more straightforward approach would be to add a timedelta to your datetime within the loop. For instance,
>>> from datetime import timedelta
>>> times = 4
>>> cur_date = datetime.date(2017, 2, 24)
>>> for _ in range(times):
print('today is {0}, do something'.format(cur_date))
cur_date += timedelta(days=7)
today is 2017-02-24, do something
today is 2017-03-03, do something
today is 2017-03-10, do something
today is 2017-03-17, do something
This could be placed in a generator as well, depending on your use case.
>>> for dt in (cur_date + timedelta(days=x*7) for x in range(times)):
print('today is {0}, do something'.format(dt))
today is 2017-02-24, do something
today is 2017-03-03, do something
today is 2017-03-10, do something
today is 2017-03-17, do something
or with Pandas pd.date_range
>>> import pandas as pd
>>> list(pd.date_range(start='2017-02-24', periods=4, freq='7D'))
[Timestamp('2017-02-24 00:00:00', freq='7D'),
Timestamp('2017-03-03 00:00:00', freq='7D'),
Timestamp('2017-03-10 00:00:00', freq='7D'),
Timestamp('2017-03-17 00:00:00', freq='7D')]
Now what would happen if you attempted this example with your approach?
>>> year, month, day = 2017, 2, 24
>>> for i in range(0 , times):
day = day
fulldateadd = datetime.date(year, month, day)
print('today is {0}, do something'.format(fulldateadd))
day = day + 7
if day > 31:
day = day - 31
month = month + 1
today is 2017-02-24, do something
ValueErrorTraceback (most recent call last)
<ipython-input-255-7df608ebbf8e> in <module>()
1 for i in range(0 , times):
2 day = day
----> 3 fulldateadd = datetime.date(year, month, day)
4 print('today is {0}, do something'.format(fulldateadd))
5 day = day + 7
ValueError: day is out of range for month
February doesn't have 31 days... so you would have to include a check with a mapping to the number of days in each month. Including logic for leap years.
How do I go about printing these:
At any given time, I should be able to return the dates of the present month in a list.
eg. Since this is March, I want to print a list [20140301, ...,20140331].
Find the difference in number of days from current date and the first of that month.
e.g. today is 4th March. I should be able to print the difference as 3
Thanks in advance
Here is what you can do in Python 2.7.3
from datetime import date
import calendar
today = date.today()
first_of_month = today.replace(day=1)
_, number_of_days_in_month = calendar.monthrange(first_of_month.year, first_of_month.month)
for i in range(1, number_of_days_in_month+1):
newdate = today.replace(day = i)
print newdate #prints all dates in months
#Lets calculate difference between 14th of this month and 1st
randomdate = today.replace(day=14)
delta = randomdate - first_of_month
print delta.days