Adding days to a date in Python using datetime and timedelta. Use Python Pandas to concatenate dates with strings.

I wanted to create 20 files with this syntax date-blog-post-name. I wrote a very extensive D3 Tutorial and wanted to break it down into smaller blog posts, published sequentially 5 days apart.

The blog posts needed to have this naming syntax:

YYYY-MM-DD-name-of-blog-post.md

I extracted the headlines H2 of the original blog post and made an array like this:

>>> posts = ['-setup-d3-step-by-step.md', '-d3-and-asynchronous.md', 
'-d3-and-incompatible-versions.md', '-d3-load-a-csv-file-with-promises.md', 
'-d3-convert-string-to-date.md', '-d3-bind-data-to-dom.md', '-d3-drawing-svg.md', 
'-d3-creating-a-bar-chart.md', '-d3-using-scales.md', '-d3-linear-scale.md', 
'-d3-band-scale.md', '-d3-scales-in-a-bar-chart.md', '-d3-responsive-visualization.md', '-d3-arrow-functions.md', '-d3-adding-axes-to-bar-chart.md', 
'-d3-bar-chart-title-and-labels.md', '-d3-visualization-margins.md', 
'-d3-mouse-event-handler.md', '-embedding-d3-in-a-website.md']

How do I add the prefix dates?

2020-05-12
2020-05-17
...

To have files like these?

2020-05-12-setup-d3-step-by-step.md
2020-05-17-d3-and-asynchronous.md
...

Adding days to a date in Python

Let’s get to it.

>>> import datetime
>>> datetime.date.today() + 5

Error:

TypeError: unsupported operand type(s) for +: 'datetime.date' and 'int'

Should I then add the days to the day in the date?

>>> datetime.date.today().day + 5
14

This can’t be right.

Adding days to date in Python with timedelta

Let’s look at the Python docs: datetime. Looking at timedelta

A timedelta object represents a duration, the difference between two dates or times.

You can do this:

new_date = old_date + datetime.timedelta(days=N)

With an example:

>>> import datetime
>>> today = datetime.date.today()
datetime.date(2020, 11, 10)

>>> tomorrow = today + datetime.timedelta(days=1)
>>> tomorrow
datetime.date(2020, 11, 11)

Let’s test this. What happens if I add 60 days:

>>> sixty_days = today + datetime.timedelta(days=60)
>>> sixty_days
datetime.date(2021, 1, 9)

Using isoformat

The syntax to create a date is:

>>> datetime.date(YYYY, M, D)

Such as:

>>> post_date = datetime.date(2020, 5, 12)
>>> post_date
datetime.date(2020, 5, 12)

However, I want the date string, not the weird date object.

>>> post_date.isoformat()
'2020-05-12'

Creating an array of dates, adding days to a date

Easy for loop:

>>> post_date
datetime.date(2020, 5, 12)

>>> date_list = []
>>> for post in range(1, 20):
        post_date += datetime.timedelta(days=5)
        date_list.append(post_date.isoformat())

Then let’s see the output

>>> date_list
['2020-05-12', '2020-05-17', '2020-05-22', '2020-05-27', '2020-06-01', 
'2020-06-06', '2020-06-11', '2020-06-16', '2020-06-21', '2020-06-26', 
'2020-07-01', '2020-07-06', '2020-07-11', '2020-07-16', '2020-07-21', 
'2020-07-26', '2020-07-31', '2020-08-05', '2020-08-10']

Now I have a date_list array with dates and a posts array with blog post names. How do I join them?

Python Pandas join strings or concatenate strings

Create two dataframes:

>>> import pandas
>>> date_list_df = pandas.DataFrame(date_list)
>>> posts_df = pandas.DataFrame(posts)

The dataframes show the data under column 0:

>>> date_list_df
	0
0   2020-05-12
1   2020-05-17
2   2020-05-22
3   2020-05-27
4   2020-06-01
5   2020-06-06
6   2020-06-11
...

>>> posts_df                                                                                                                                                                 
	0
0	-setup-d3-step-by-step.md
1	-d3-and-asynchronous.md
2	-d3-and-incompatible-versions.md
3	-d3-load-a-csv-file-with-promises.md
4	-d3-convert-string-to-date.md
5	-d3-bind-data-to-dom.md
6	-d3-drawing-svg.md
...

I tried join but this didn’t work:

>>> date_list_df.join(posts_df)

ValueError: columns overlap but no suffix specified: RangeIndex(start=0, stop=1, step=1)

Add names to the columns:

>>> posts_df.columns = ['post_name']
>>> date_list_df.columns = ['date']

Tried join again but this isn’t what I wanted to do:

>>> date_list_df.join(posts_df)

          date                  post_name
0   2020-05-12  -setup-d3-step-by-step.md
1   2020-05-17  -d3-and-asynchronous.md
2   2020-05-22  -d3-and-incompatible-versions.md
3   2020-05-27  -d3-load-a-csv-file-with-promises.md
4   2020-06-01  -d3-convert-string-to-date.md
5   2020-06-06  -d3-bind-data-to-dom.md
6   2020-06-11  -d3-drawing-svg.md

I want to concatenate the date with the post name:

>>> posts_names = date_list_df['date'].str.cat(posts_df['post_name'])

0    2020-05-12-setup-d3-step-by-step.md
1    2020-05-17-d3-and-asynchronous.md
2    2020-05-22-d3-and-incompatible-versions.md
3    2020-05-27-d3-load-a-csv-file-with-promises.md
4    2020-06-01-d3-convert-string-to-date.md
5    2020-06-06-d3-bind-data-to-dom.md
6    2020-06-11-d3-drawing-svg.md

Then create an array from the dataframe:

>>> posts_names_array = posts_names.array

Copying and creating many files in Python

I wanted to do the same you do on the shell:

$ cp source_file new_file

And repeat for all the posts names in posts_names_array.

Use the Python modules os and shutil.

>>> import os
>>> import shutil

>>> dest_dir = '_posts/'
>>> source_post = '_posts/2020-02-02-d3-tutorial-data-visualization.md'

Then go through the array:

>>> for post in posts_names_array:
		shutil.copy2(source_post, dest_dir+post)

Output:

'_posts/2020-05-12-setup-d3-step-by-step.md'
'_posts/2020-05-17-d3-and-asynchronous.md'
'_posts/2020-05-22-d3-and-incompatible-versions.md'
'_posts/2020-05-27-d3-load-a-csv-file-with-promises.md'
'_posts/2020-06-01-d3-convert-string-to-date.md'
'_posts/2020-06-06-d3-bind-data-to-dom.md'
'_posts/2020-06-11-d3-drawing-svg.md'
...

Ask me anything on Linkedin