Reputation: 1735
I am trying find an efficient way of creating a list of dates only including the first day of the month for a given period. Something like this but better:
import datetime
dates = [
datetime.date (2014, 4, 1),
datetime.date (2014, 5, 1),
datetime.date (2014, 6, 1),
datetime.date (2014, 7, 1),
datetime.date (2014, 8, 1),
datetime.date (2014, 9, 1),
datetime.date (2014, 10, 1),
datetime.date (2014, 11, 1),
datetime.date (2014, 12, 1),
datetime.date (2015, 1, 1),
datetime.date (2015, 2, 1)]
Alternatively, some direction on what to Google for this. Cheers!
Upvotes: 14
Views: 22726
Reputation: 61
Try pandas.date_range() with the 'MS' (Month Start) frequency alias:
import pandas as pd
start = '2020-01-01'
end = '2020-12-01'
dates = pd.date_range(start, end, freq='MS')
print(dates)
Result:
DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01',
'2020-05-01', '2020-06-01', '2020-07-01', '2020-08-01',
'2020-09-01', '2020-10-01', '2020-11-01', '2020-12-01'],
dtype='datetime64[ns]', freq='MS')
A list of all frequency aliases can be found here.
Upvotes: 6
Reputation: 64328
This is the same as @Andrew's answer, but much faster:
dates = []
date = datetime.date.today()
while date.year < 2015:
if date.day == 1:
dates.append(date)
# I added the following line:
date += datetime.timedelta(days=27)
date += datetime.timedelta(days=1)
Using force, but not being brutal.
Upvotes: 0
Reputation: 1
import datetime
import calendar
import re
from datetime import date
def findDay(date):
born = datetime.datetime.strptime(date, '%Y %m %d').weekday()
return (calendar.day_name[born])
def hyp(j):
no_hyphens = re.sub('-',' ',str(j))
return no_hyphens
def send(year_start):
date = hyp(year_start)
print (date)
print(findDay(date))
epoch_year = 2019
for i in range(1,13):
year_start = date(epoch_year, i, 1)
send(year_start)
Upvotes: 0
Reputation: 221
With pandas :
dates= pd.date_range('2018-01-01','2020-01-01' , freq='1M')-pd.offsets.MonthBegin(1)
result :
`DatetimeIndex(['2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01',
'2018-05-01', '2018-06-01', '2018-07-01', '2018-08-01',
'2018-09-01', '2018-10-01', '2018-11-01', '2018-12-01',
'2019-01-01', '2019-02-01', '2019-03-01', '2019-04-01',
'2019-05-01', '2019-06-01', '2019-07-01', '2019-08-01',
'2019-09-01', '2019-10-01', '2019-11-01', '2019-12-01'],
dtype='datetime64[ns]', freq='MS')
Upvotes: 22
Reputation: 27247
>>> startyear = 2014
>>> startmonth = 4
>>> endyear = 2015
>>> endmonth = 2
>>> [datetime.date(m/12, m%12+1, 1) for m in xrange(startyear*12+startmonth-1, endyear*12+endmonth)]
[datetime.date(2014, 4, 1), datetime.date(2014, 5, 1), datetime.date(2014, 6, 1), datetime.date(2014, 7, 1), datetime.date(2014, 8, 1), datetime.date(2014, 9, 1), datetime.date(2014, 10, 1), datetime.date(2014, 11, 1), datetime.date(2014, 12, 1), datetime.date(2015, 1, 1), datetime.date(2015, 2, 1)]
For Python 3, you'll need to use range
instead of xrange
, and //
(floor division) instead of /
(which does float division in Python 3):
[datetime.date(m//12, m%12+1, 1) for m in range(startyear*12+startmonth-1, endyear*12+endmonth)]
Upvotes: 8
Reputation: 4647
You can use relativedelta from dateutil, and then create a function to use any date range:
from datetime import date
from dateutil.relativedelta import relativedelta
def mthStList(start_date, end_date):
stdt_list = []
cur_date = start_date.replace(day=1) # sets date range to start of month
while cur_date <= end_date:
stdt_list.append(cur_date)
cur_date += relativedelta(months=+1)
return stdt_list
mthStList(date(2012, 5, 26), date.today())
Upvotes: 2
Reputation: 7821
There is no reason to bruteforce this:
import datetime
from pprint import pprint
dt = datetime.date.today()
end = datetime.date(2015, 2, 1)
dates = []
while dt < end:
if not dt.month % 12:
dt = datetime.date(dt.year+1, 1, 1)
else:
dt = datetime.date(dt.year, dt.month+1, 1)
dates.append(dt)
pprint(dates)
Output:
[datetime.date(2014, 4, 1),
datetime.date(2014, 5, 1),
datetime.date(2014, 6, 1),
datetime.date(2014, 7, 1),
datetime.date(2014, 8, 1),
datetime.date(2014, 9, 1),
datetime.date(2014, 10, 1),
datetime.date(2014, 11, 1),
datetime.date(2014, 12, 1),
datetime.date(2015, 1, 1),
datetime.date(2015, 2, 1)]
Upvotes: 2
Reputation: 10846
If you're only creating the list for a few years then efficiency should not be a concern. Clarity of code is the most important aspect.
dates = []
date = datetime.date.today()
while date.year < 2015:
if date.day == 1:
dates.append(date)
date += datetime.timedelta(days=1)
Upvotes: 8