The first thing I would do is convert to datetime objects:
records['start date']=pd.to_datetime(records['start date'])
records['end date']=pd.to_datetime(records['end date'])
Then I can work with these rather than strings:
import datetime as dt
# I sort based on name and start date:
records2=records.sort_values(['name', 'start date'])
I then create a new column, which compares the start date to the end date, and returns True if a job overlaps with the subsequent job (False otherwise). This is more specific than what you asked, as it gets to the job level, but you could change this to be True if any jobs overlap for a person.
records2['overlap']=(records2['end date']-records2['start date'].shift(-1).where(records2['name'].eq(records2['name'].shift(-1))))>dt.timedelta(0)
records2
Which returns:
name job code start date end date overlap
1 Harry 101 2020-01-01 2020-04-30 False
4 Harry 401 2020-05-01 2020-12-31 False
2 Jack 301 2020-01-01 2020-12-31 False
3 Matt 101 2020-01-01 2020-11-30 True
5 Matt 102 2020-06-15 2020-12-31 False
0 Tom 101 2020-01-01 2020-12-31 False
This is a helpful question for using shift in conjunction with groups, and there are some nice and different ways to do this. I pulled from the second answer.
If you're interested in how many times each person has an overlap, you can use the following code to create a dataframe with that information:
df=records2.groupby('name').sum('overlap')
df
Which returns:
job code overlap
name
Harry 502 0
Jack 301 0
Matt 203 1
Tom 101 0