Hi everyone!
I'm trying to generate list with dates of current month, but it generates wrong: from 2nd january to 1st february, I need list starts from 1st day of current month to last - 1 to 31, for example.
I have already searched the site and on Google, but so far I have not found anything. What am I doing wrong?
import datetime
year = 2021
month = 1
my_date = datetime.date(year, month, 1)
delta = datetime.timedelta(days=1)
dates = []
while my_date.month == month:
dates.append((my_date + delta).strftime('%d-%b-%Y'))
my_date += delta
print(dates)
print(len(dates))
That's because you are adding the date delta twice. Remove the first delta addition:
import datetime
year = 2021
month = 1
my_date = datetime.date(year, month, 1)
delta = datetime.timedelta(days=1)
dates = []
while my_date.month == month:
dates.append((my_date).strftime('%d-%b-%Y'))
my_date += delta
print(dates)
print(len(dates))
Output:
>>> print(dates)
['01-Jan-2021', '02-Jan-2021', '03-Jan-2021', '04-Jan-2021', '05-Jan-2021', '06-Jan-2021', '07-Jan-2021', '08-Jan-2021', '09-Jan-2021', '10-Jan-2021', '11-Jan-2021', '12-Jan-2021', '13-Jan-2021', '14-Jan-2021', '15-Jan-2021', '16-Jan-2021', '17-Jan-2021', '18-Jan-2021', '19-Jan-2021', '20-Jan-2021', '21-Jan-2021', '22-Jan-2021', '23-Jan-2021', '24-Jan-2021', '25-Jan-2021', '26-Jan-2021', '27-Jan-2021', '28-Jan-2021', '29-Jan-2021', '30-Jan-2021', '31-Jan-2021']
>>> print(len(dates))
31
Related
I would like to create a new column in my dataframe which is equal to the last business day of the month based on the US calendar, ideally in the format mm/dd/yyyy. My goal is to create this variable per day and set it for every day in the month corresponding to my existing 'DATES' column. For example, for every day in January I want to create a a variable equal to '01/31/2020', in a string format. For everyday in February I want to set a variable equal to '02/28/2020', in string format.
If anyone has ideas would be of great help!
Dataframe example
This works for me
from datetime import date,timedelta
import datetime
import calendar
today=datetime.date.today()
last = today.replace(day=calendar.monthrange(today.year,today.month)[1])
if last.weekday()<5:
print(last)
else:
print(last-timedelta(days=1+last.weekday()-5))
>>> import datetime
>>> def is_weekend(dt):
return dt.weekday() >= 5
>>> def is_holiday(dt):
return False # You'll need to provide your own definition of holidays
>>> def last_workday(year, month, count=1):
while count > 0:
next_month = month + 1
if next_month <= 12:
next_year = year
else:
next_month = 1
next_year = year + 1
dt = datetime.datetime(next_year, next_month, 1) - datetime.timedelta(days=1)
while is_weekend(dt) or is_holiday(dt):
dt -= datetime.timedelta(days=1)
yield dt
year = next_year
month = next_month
count -= 1
>>> for x in last_workday(2020, 1, 12):
print(x.strftime('%m/%d/%Y'))
01/31/2020
02/28/2020
03/31/2020
04/30/2020
05/29/2020
06/30/2020
07/31/2020
08/31/2020
09/30/2020
10/30/2020
11/30/2020
12/31/2020
I can not figure out how to take the year, day and week to return the month. Right now I am just trying to develop a Python Script that will do this. The goal after finishing this script is to use it for a Spark SQL Query to find the month since in my data I am given a day, year and week in each row.
As of now my python code looks like so. This code only works for the statement I have into the print(getmonth(2, 30 ,2018) returning 7. I have tried other dates and the output is only "None". I have tried variables also, but no success there.
import datetime
def month(day, week, year):
for month in range(1,13):
try:
date = datetime.datetime(year, month, day)
except ValueError:
iso_year, iso_weeknum, iso_weekday = date.isocalendar()
if iso_weeknum == week:
return date.month
print(getmonth(2, 30, 2018))
#iso_(year,weeknum,weekday) are the classes for ISO. Year is 1-9999, weeknum is 0-52 or 53, and weekday is 0-6
#isocaldenar is a tuple (year, week#, weekday)
I don't really understand your questions, but i think datetime will work... sorce: Get date from ISO week number in Python:
>>> from datetime import datetime
>>> day = 28
>>> week = 30
>>> year = 2018
>>> t = datetime.strptime('{}_{}_{}{}'.format(day,week,year,-0), '%d_%W_%Y%w')
>>> t.strftime('%W')
'30'
>>> t.strftime('%m')
'07'
>>>
A simpler solution can be created using the pendulum library. As in your code, loop through month numbers, create dates, compare the weeks for these dates against the desired date. If found halt the loop; if the date is not seen then exit the loop with, say, a -1.
>>> import pendulum
>>> for month in range(1,13):
... date = pendulum.create(2018, month, 28)
... if date.week_of_year == 30:
... break
... else:
... month = -1
...
>>> month
7
>>> date
<Pendulum [2018-07-28T00:00:00+00:00]>
Here is a brute force method that loops through the days of the year (It expects the day as Monday being 0 and Sunday being 6, it also returns the Month 0 indexed, January being 0 and December being 11):
import datetime
def month(day, week, year):
#Generate list of No of days of the month
months = [31,28,31,30,31,30,31,31,30,31,30,31]
if((year % 4 == 0 and year % 100 != 0) or year % 400 == 0): months[1] += 1
#ISO wk1 of the yr is the first wk with a thursday, otherwise it's wk53 of the previous yr
currentWeek = 1 if day < 4 else 0
#The day that the chosen year started on
currentDay = datetime.datetime(year, 1, 1).weekday()
#Loop over every day of the year
for i in range(sum(months)):
#If the week is correct and day is correct you're done
if day == currentDay and week == currentWeek:
return months.index(next(filter(lambda x: x!=0, months)))
#Otherwise, go to next day of wk/next wk of yr
currentDay = (currentDay + 1) % 7
if currentDay == 0:
currentWeek += 1
#And decrement counter for current month
months[months.index(next(filter(lambda x: x!=0, months)))]-=1
print(month(2, 30, 2018)) # 6 i.e. July
months.index(next(filter(lambda x: x!=0, months))) is used to get the first month of that we haven't used all of the days of, i.e. the month you're currently in.
is there any way to generate all the dates of a particular month when the month and year are inputted?
I have
daterange = date_range(date1, date2)
dates=[]
for x in daterange:
dates.append((x.strftime('%Y-%m-%d')))
using pandas, but how can I account for different month lengths?
You could use pd.offsets.MonthBegin and then use an end exclusive daily date range:
dts = pd.date_range(month_start, month_start + pd.offsets.MonthBegin(1), closed="left")
I find I can't import calendar on my system, so here's a datetime-only solution:
from datetime import date, timedelta
month, year = 2, 2008
day = timedelta(days=1)
date1 = date(year, month, 1)
dates = []
d = date1
while d.month == month:
dates.append(d)
d += day
(Creates a list of the dates of days in February 2008, a leap year). If you want string representations of the dates, you can use:
from datetime import timedelta, datetime
month, year = 2, 2008
day = timedelta(days=1)
date1 = datetime(year, month, 1)
d = date1
dates = []
while d.month == month:
dates.append(d.strftime('%Y-%m-%d'))
d += day
You can do that with the calendar module:
import calendar
date_of_first_weekday, number_days_in_month = calendar.monthrange(year, month)
The calendar module has all you need:
import calendar
first_weekday, month_days = calendar.monthrange(year, month)
for mday in xrange(1, month_days + 1):
print mday
I want to know how you get the months by the giving day, week number and year.
For example if you have something like this
def getmonth(day, week, year):
# by day, week and year calculate the month
print (month)
getmonth(28, 52, 2014)
# print 12
getmonth(13, 42, 2014)
# print 10
getmonth(6, 2, 2015)
# print 1
Per interjay's suggestion:
import datetime as DT
def getmonth(day, week, year):
for month in range(1, 13):
try:
date = DT.datetime(year, month, day)
except ValueError:
continue
iso_year, iso_weeknum, iso_weekday = date.isocalendar()
if iso_weeknum == week:
return date.month
print(getmonth(28, 52, 2014))
# 12
print(getmonth(13, 42, 2014))
# 10
print(getmonth(6, 2, 2015))
# 1
You can do it with the isoweek module, something like this for your first example:
from isoweek import Week
w = Week(2014, 52)
candidates = [date for date in w.days() if date.day == 28]
assert len(candidates) == 1
date = candidates[0] # your answer
I'm using python-dateutil when I need to implement some tricky date operations.
from datetime import date
from dateutil.rrule import YEARLY, rrule
def get_month(day, week, year):
rule = rrule(YEARLY, byweekno=week, bymonthday=day, dtstart=date(year, 1, 1))
return rule[0].month
from datetime import datetime, timedelta
def getmonth(day, week, year):
d = datetime.strptime('%s %s 1' % (week-1, year), '%W %Y %w')
for i in range(0, 7):
d2 = d + timedelta(days=i)
if d2.day == day:
return d2.month
Hello sorry for the ambiguous title, here's what I want to do :
I have a string:
month = '1406'
that corresponds to the month of June, 2014.
How can I dynamically say that that string represents the month of June and I specifically want the last day of the month.
So I want to write it in the format: '%Y-%m-%d %H:%M:%S' and have:
'2014-06-30 00:00:00'
You get the last day of a given month with the calendar.monthrange() function. Turn your string into two integers (month, year), create a datetime object from the year, month and last day of the month:
from datetime import datetime
from calendar import monthrange
year, month = int(month[:2]), int(month[2:])
year += 2000 # assume this century
day = monthrange(year, month)[1]
dt = datetime(year, month, day) # time defaults to 00:00:00
Demo:
>>> from datetime import datetime
>>> from calendar import monthrange
>>> month = '1406'
>>> year, month = int(month[:2]), int(month[2:])
>>> year += 2000 # assume this century
>>> day = monthrange(year, month)[1]
>>> datetime(year, month, day)
datetime.datetime(2014, 6, 30, 0, 0)
>>> print datetime(year, month, day)
2014-06-30 00:00:00
The default string conversion for datetime objects fits your desired format already; you can make it explicit by calling str() on it or by using the datetime.datetime.isoformat() method, as you see fit.
This seems to do the trick:
import datetime
mon = '1406'
y, m = divmod(int(mon), 100)
dt = datetime.datetime(2000 + y + m // 12, m % 12 + 1, 1) - datetime.timedelta(days=1)
print dt