diff --git a/app/assets/javascripts/contributors/components/contributors.vue b/app/assets/javascripts/contributors/components/contributors.vue
index 9b8347934286a9b4219cf417df3f3ef3cc5e11ae..78d17a619fb739749c52c6b8abcb0c571a251df2 100644
--- a/app/assets/javascripts/contributors/components/contributors.vue
+++ b/app/assets/javascripts/contributors/components/contributors.vue
@@ -11,11 +11,14 @@ import { __ } from '~/locale';
 import RefSelector from '~/ref/components/ref_selector.vue';
 import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
 import { xAxisLabelFormatter, dateFormatter } from '../utils';
+import { MASTER_CHART_HEIGHT } from '../constants';
 import ContributorAreaChart from './contributor_area_chart.vue';
+import IndividualChart from './individual_chart.vue';
 
 const GRAPHS_PATH_REGEX = /^(.*?)\/-\/graphs/g;
 
 export default {
+  MASTER_CHART_HEIGHT,
   i18n: {
     history: __('History'),
     refSelectorTranslations: {
@@ -27,6 +30,7 @@ export default {
     GlButton,
     GlLoadingIcon,
     ContributorAreaChart,
+    IndividualChart,
     RefSelector,
   },
   props: {
@@ -52,9 +56,8 @@ export default {
     return {
       masterChart: null,
       individualCharts: [],
+      individualChartZoom: {},
       svgs: {},
-      masterChartHeight: 264,
-      individualChartHeight: 216,
       selectedBranch: this.branch,
     };
   },
@@ -195,23 +198,13 @@ export default {
           });
         })
         .catch(() => {});
-      this.masterChart.on('datazoom', debounce(this.setIndividualChartsZoom, 200));
-    },
-    onIndividualChartCreated(chart) {
-      this.individualCharts.push(chart);
-    },
-    setIndividualChartsZoom(options) {
-      this.charts.forEach((chart) =>
-        chart.setOption(
-          {
-            dataZoom: {
-              start: options.start,
-              end: options.end,
-              show: false,
-            },
-          },
-          { lazyUpdate: true },
-        ),
+
+      this.masterChart.on(
+        'datazoom',
+        debounce(() => {
+          const [{ startValue, endValue }] = this.masterChart.getOption().dataZoom;
+          this.individualChartZoom = { startValue, endValue };
+        }, 200),
       );
     },
     visitBranch(selected) {
@@ -230,7 +223,7 @@ export default {
     </div>
 
     <template v-else-if="showChart">
-      <div class="gl-border-b gl-border-gray-100 gl-mb-6 gl-bg-gray-10 gl-p-5">
+      <div class="gl-border-b gl-border-gray-100 gl-mb-6 gl-bg-gray-10 gl-py-5">
         <div class="gl-display-flex">
           <div class="gl-mr-3">
             <ref-selector
@@ -246,35 +239,25 @@ export default {
           </gl-button>
         </div>
       </div>
-      <div data-testid="contributors-charts">
-        <h4 class="gl-mb-2 gl-mt-5">{{ __('Commits to') }} {{ branch }}</h4>
-        <span>{{ __('Excluding merge commits. Limited to 6,000 commits.') }}</span>
-        <contributor-area-chart
-          class="gl-mb-5"
-          :data="masterChartData"
-          :option="masterChartOptions"
-          :height="masterChartHeight"
-          @created="onMasterChartCreated"
-        />
 
-        <div class="row">
-          <div
-            v-for="(contributor, index) in individualChartsData"
-            :key="index"
-            class="col-lg-6 col-12 gl-my-5"
-          >
-            <h4 class="gl-mb-2 gl-mt-0">{{ contributor.name }}</h4>
-            <p class="gl-mb-3">
-              {{ n__('%d commit', '%d commits', contributor.commits) }} ({{ contributor.email }})
-            </p>
-            <contributor-area-chart
-              :data="contributor.dates"
-              :option="individualChartOptions"
-              :height="individualChartHeight"
-              @created="onIndividualChartCreated"
-            />
-          </div>
-        </div>
+      <h4 class="gl-mb-2 gl-mt-5">{{ __('Commits to') }} {{ branch }}</h4>
+      <span>{{ __('Excluding merge commits. Limited to 6,000 commits.') }}</span>
+      <contributor-area-chart
+        class="gl-mb-5"
+        :data="masterChartData"
+        :option="masterChartOptions"
+        :height="$options.MASTER_CHART_HEIGHT"
+        @created="onMasterChartCreated"
+      />
+
+      <div class="row">
+        <individual-chart
+          v-for="(contributor, index) in individualChartsData"
+          :key="index"
+          :contributor="contributor"
+          :chart-options="individualChartOptions"
+          :zoom="individualChartZoom"
+        />
       </div>
     </template>
   </div>
diff --git a/app/assets/javascripts/contributors/components/individual_chart.vue b/app/assets/javascripts/contributors/components/individual_chart.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1d23273fd0295bbd6a035935852824c2746c6caf
--- /dev/null
+++ b/app/assets/javascripts/contributors/components/individual_chart.vue
@@ -0,0 +1,86 @@
+<script>
+import { isNumber } from 'lodash';
+import { isInTimePeriod } from '~/lib/utils/datetime/date_calculation_utility';
+import { INDIVIDUAL_CHART_HEIGHT } from '../constants';
+import ContributorAreaChart from './contributor_area_chart.vue';
+
+export default {
+  INDIVIDUAL_CHART_HEIGHT,
+  components: {
+    ContributorAreaChart,
+  },
+  props: {
+    contributor: {
+      type: Object,
+      required: true,
+    },
+    chartOptions: {
+      type: Object,
+      required: true,
+    },
+    zoom: {
+      type: Object,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      chart: null,
+    };
+  },
+  computed: {
+    hasZoom() {
+      const { startValue, endValue } = this.zoom;
+      return isNumber(startValue) && isNumber(endValue);
+    },
+    commitCount() {
+      if (!this.hasZoom) return this.contributor.commits;
+
+      const start = new Date(this.zoom.startValue);
+      const end = new Date(this.zoom.endValue);
+
+      return this.contributor.dates[0].data
+        .filter(([date, count]) => count > 0 && isInTimePeriod(new Date(date), start, end))
+        .map(([, count]) => count)
+        .reduce((acc, count) => acc + count, 0);
+    },
+  },
+  watch: {
+    chart() {
+      this.syncChartZoom();
+    },
+    zoom() {
+      this.syncChartZoom();
+    },
+  },
+  methods: {
+    onChartCreated(chart) {
+      this.chart = chart;
+    },
+    syncChartZoom() {
+      if (!this.hasZoom || !this.chart) return;
+
+      const { startValue, endValue } = this.zoom;
+      this.chart.setOption(
+        { dataZoom: { startValue, endValue, show: false } },
+        { lazyUpdate: true },
+      );
+    },
+  },
+};
+</script>
+
+<template>
+  <div class="col-lg-6 col-12 gl-my-5">
+    <h4 class="gl-mb-2 gl-mt-0" data-testid="chart-header">{{ contributor.name }}</h4>
+    <p class="gl-mb-3" data-testid="commit-count">
+      {{ n__('%d commit', '%d commits', commitCount) }} ({{ contributor.email }})
+    </p>
+    <contributor-area-chart
+      :data="contributor.dates"
+      :option="chartOptions"
+      :height="$options.INDIVIDUAL_CHART_HEIGHT"
+      @created="onChartCreated"
+    />
+  </div>
+</template>
diff --git a/app/assets/javascripts/contributors/constants.js b/app/assets/javascripts/contributors/constants.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c641c83e970b4e219652a631d0414fbb73e8bc9
--- /dev/null
+++ b/app/assets/javascripts/contributors/constants.js
@@ -0,0 +1,2 @@
+export const MASTER_CHART_HEIGHT = 264;
+export const INDIVIDUAL_CHART_HEIGHT = 216;
diff --git a/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js b/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js
index 9bb2884e065f2a2c2844549931bda8aa7152f548..73cb64519aac0cd9a773abbd6f299d31fa02107f 100644
--- a/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js
@@ -667,6 +667,17 @@ export const isInFuture = (date) =>
  */
 export const fallsBefore = (dateA, dateB) => differenceInMilliseconds(dateA, dateB) > 0;
 
+/**
+ * Checks whether date falls in the `start -> end` time period.
+ *
+ * @param {Date} date
+ * @param {Date} start
+ * @param {Date} end
+ * @return {Boolean} Returns true if date falls in the time period, otherwise false
+ */
+export const isInTimePeriod = (date, start, end) =>
+  differenceInMilliseconds(start, date) >= 0 && differenceInMilliseconds(date, end) >= 0;
+
 /**
  * Removes the time component of the date.
  *
diff --git a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap
deleted file mode 100644
index 50a4a21ef1f8414f007567b0d42370e75f45bd29..0000000000000000000000000000000000000000
--- a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap
+++ /dev/null
@@ -1,120 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Contributors charts should render charts and a RefSelector when loading completed and there is chart data 1`] = `
-<div>
-  <div
-    class="gl-bg-gray-10 gl-border-b gl-border-gray-100 gl-mb-6 gl-p-5"
-  >
-    <div
-      class="gl-display-flex"
-    >
-      <div
-        class="gl-mr-3"
-      >
-        <refselector-stub
-          enabledreftypes="REF_TYPE_BRANCHES,REF_TYPE_TAGS"
-          name=""
-          projectid="23"
-          state="true"
-          translations="[object Object]"
-          value="main"
-        />
-      </div>
-      <a
-        class="btn btn-default btn-md gl-button"
-        data-testid="history-button"
-        href="some/path"
-      >
-        <span
-          class="gl-button-text"
-        >
-          History
-        </span>
-      </a>
-    </div>
-  </div>
-  <div
-    data-testid="contributors-charts"
-  >
-    <h4
-      class="gl-mb-2 gl-mt-5"
-    >
-      Commits to main
-    </h4>
-    <span>
-      Excluding merge commits. Limited to 6,000 commits.
-    </span>
-    <glareachart-stub
-      class="gl-mb-5"
-      data="[object Object]"
-      format-tooltip-text="function () { [native code] }"
-      height="264"
-      option="[object Object]"
-      responsive=""
-      width="auto"
-    >
-      <div
-        data-testid="tooltip-title"
-      />
-      <div
-        class="gl-display-flex gl-gap-6 gl-justify-content-space-between"
-      >
-        <span
-          data-testid="tooltip-label"
-        >
-          Number of commits
-        </span>
-        <span
-          data-testid="tooltip-value"
-        >
-          []
-        </span>
-      </div>
-    </glareachart-stub>
-    <div
-      class="row"
-    >
-      <div
-        class="col-12 col-lg-6 gl-my-5"
-      >
-        <h4
-          class="gl-mb-2 gl-mt-0"
-        >
-          John
-        </h4>
-        <p
-          class="gl-mb-3"
-        >
-          2 commits (jawnnypoo@gmail.com)
-        </p>
-        <glareachart-stub
-          data="[object Object]"
-          format-tooltip-text="function () { [native code] }"
-          height="216"
-          option="[object Object]"
-          responsive=""
-          width="auto"
-        >
-          <div
-            data-testid="tooltip-title"
-          />
-          <div
-            class="gl-display-flex gl-gap-6 gl-justify-content-space-between"
-          >
-            <span
-              data-testid="tooltip-label"
-            >
-              Commits
-            </span>
-            <span
-              data-testid="tooltip-value"
-            >
-              []
-            </span>
-          </div>
-        </glareachart-stub>
-      </div>
-    </div>
-  </div>
-</div>
-`;
diff --git a/spec/frontend/contributors/component/contributors_spec.js b/spec/frontend/contributors/component/contributors_spec.js
index 6235d2610a94d1c887594496f2a28ffa38ab19da..ac06111155f97f8e887b3a897c87862b7115b736 100644
--- a/spec/frontend/contributors/component/contributors_spec.js
+++ b/spec/frontend/contributors/component/contributors_spec.js
@@ -1,14 +1,17 @@
 import MockAdapter from 'axios-mock-adapter';
 import { nextTick } from 'vue';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
-import ContributorsCharts from '~/contributors/components/contributors.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import Contributors from '~/contributors/components/contributors.vue';
 import { createStore } from '~/contributors/stores';
+import { MASTER_CHART_HEIGHT } from '~/contributors/constants';
 import axios from '~/lib/utils/axios_utils';
 import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
 import { visitUrl } from '~/lib/utils/url_utility';
 import RefSelector from '~/ref/components/ref_selector.vue';
 import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
 import { SET_CHART_DATA, SET_LOADING_STATE } from '~/contributors/stores/mutation_types';
+import ContributorAreaChart from '~/contributors/components/contributor_area_chart.vue';
+import IndividualChart from '~/contributors/components/individual_chart.vue';
 
 jest.mock('~/lib/utils/url_utility', () => ({
   visitUrl: jest.fn(),
@@ -28,36 +31,32 @@ const chartData = [
 const projectId = '23';
 const commitsPath = 'some/path';
 
-function factory() {
+const createWrapper = () => {
   mock = new MockAdapter(axios);
   jest.spyOn(axios, 'get');
   mock.onGet().reply(HTTP_STATUS_OK, chartData);
   store = createStore();
 
-  wrapper = mountExtended(ContributorsCharts, {
+  wrapper = shallowMountExtended(Contributors, {
     propsData: {
       endpoint,
       branch,
       projectId,
       commitsPath,
     },
-    stubs: {
-      GlLoadingIcon: true,
-      GlAreaChart: true,
-      RefSelector: true,
-    },
     store,
   });
-}
+};
 
 const findLoadingIcon = () => wrapper.findByTestId('loading-app-icon');
 const findRefSelector = () => wrapper.findComponent(RefSelector);
 const findHistoryButton = () => wrapper.findByTestId('history-button');
-const findContributorsCharts = () => wrapper.findByTestId('contributors-charts');
+const findMasterChart = () => wrapper.findComponent(ContributorAreaChart);
+const findIndividualCharts = () => wrapper.findAllComponents(IndividualChart);
 
-describe('Contributors charts', () => {
+describe('Contributors', () => {
   beforeEach(() => {
-    factory();
+    createWrapper();
   });
 
   afterEach(() => {
@@ -74,43 +73,95 @@ describe('Contributors charts', () => {
     expect(findLoadingIcon().exists()).toBe(true);
   });
 
-  it('should render charts and a RefSelector when loading completed and there is chart data', async () => {
-    store.commit(SET_LOADING_STATE, false);
-    store.commit(SET_CHART_DATA, chartData);
-    await nextTick();
+  describe('loading complete', () => {
+    beforeEach(() => {
+      store.commit(SET_LOADING_STATE, false);
+      store.commit(SET_CHART_DATA, chartData);
+      return nextTick();
+    });
 
-    expect(findLoadingIcon().exists()).toBe(false);
-    expect(findRefSelector().exists()).toBe(true);
-    expect(findRefSelector().props()).toMatchObject({
-      enabledRefTypes: [REF_TYPE_BRANCHES, REF_TYPE_TAGS],
-      value: branch,
-      projectId,
-      translations: { dropdownHeader: 'Switch branch/tag' },
-      useSymbolicRefNames: false,
-      state: true,
-      name: '',
+    it('does not display loading spinner', () => {
+      expect(findLoadingIcon().exists()).toBe(false);
     });
-    expect(findContributorsCharts().exists()).toBe(true);
-    expect(wrapper.element).toMatchSnapshot();
-  });
 
-  it('should have a history button with a set href attribute', async () => {
-    store.commit(SET_LOADING_STATE, false);
-    store.commit(SET_CHART_DATA, chartData);
-    await nextTick();
+    it('renders the RefSelector', () => {
+      expect(findRefSelector().props()).toMatchObject({
+        enabledRefTypes: [REF_TYPE_BRANCHES, REF_TYPE_TAGS],
+        value: branch,
+        projectId,
+        translations: { dropdownHeader: 'Switch branch/tag' },
+        useSymbolicRefNames: false,
+        state: true,
+        name: '',
+      });
+    });
 
-    const historyButton = findHistoryButton();
-    expect(historyButton.exists()).toBe(true);
-    expect(historyButton.attributes('href')).toBe(commitsPath);
-  });
+    it('should have a history button with a set href attribute', () => {
+      const historyButton = findHistoryButton();
+      expect(historyButton.exists()).toBe(true);
+      expect(historyButton.attributes('href')).toBe(commitsPath);
+    });
 
-  it('visits a URL when clicking on a branch/tag', async () => {
-    store.commit(SET_LOADING_STATE, false);
-    store.commit(SET_CHART_DATA, chartData);
-    await nextTick();
+    it('visits a URL when clicking on a branch/tag', () => {
+      findRefSelector().vm.$emit('input', branch);
 
-    findRefSelector().vm.$emit('input', branch);
+      expect(visitUrl).toHaveBeenCalledWith(`${endpoint}/${branch}`);
+    });
 
-    expect(visitUrl).toHaveBeenCalledWith(`${endpoint}/${branch}`);
+    it('renders the master chart', () => {
+      expect(findMasterChart().props()).toMatchObject({
+        data: [{ name: 'Commits', data: expect.any(Array) }],
+        height: MASTER_CHART_HEIGHT,
+        option: {
+          xAxis: {
+            data: expect.any(Array),
+            splitNumber: 24,
+            min: '2019-03-03',
+            max: '2019-05-05',
+          },
+          yAxis: { name: 'Number of commits' },
+          grid: { bottom: 64, left: 64, right: 20, top: 20 },
+        },
+      });
+    });
+
+    it('renders the individual charts', () => {
+      expect(findIndividualCharts().length).toBe(1);
+      expect(findIndividualCharts().at(0).props()).toMatchObject({
+        contributor: {
+          name: 'John',
+          email: 'jawnnypoo@gmail.com',
+          commits: 2,
+          dates: [expect.any(Object)],
+        },
+        chartOptions: {
+          xAxis: {
+            data: expect.any(Array),
+            splitNumber: 18,
+            min: '2019-03-03',
+            max: '2019-05-05',
+          },
+          yAxis: { name: 'Commits', max: 1 },
+          grid: { bottom: 27, left: 64, right: 20, top: 8 },
+        },
+        zoom: {},
+      });
+    });
+
+    describe('master chart was zoomed', () => {
+      const zoom = { startValue: 100, endValue: 200 };
+
+      beforeEach(() => {
+        findMasterChart().vm.$emit('created', {
+          setOption: jest.fn(),
+          on: jest.fn().mockImplementation((_, callback) => callback()),
+          getOption: jest.fn().mockImplementation(() => ({ dataZoom: [zoom] })),
+        });
+      });
+
+      it('sets the individual chart zoom', () => {
+        expect(findIndividualCharts().at(0).props('zoom')).toEqual(zoom);
+      });
+    });
   });
 });
diff --git a/spec/frontend/contributors/component/individual_chart_spec.js b/spec/frontend/contributors/component/individual_chart_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..571e65c812a24ad3f45daf348f5a643a02194c3a
--- /dev/null
+++ b/spec/frontend/contributors/component/individual_chart_spec.js
@@ -0,0 +1,114 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { INDIVIDUAL_CHART_HEIGHT } from '~/contributors/constants';
+import IndividualChart from '~/contributors/components/individual_chart.vue';
+import ContributorAreaChart from '~/contributors/components/contributor_area_chart.vue';
+
+describe('Individual chart', () => {
+  let wrapper;
+  let mockChart;
+
+  const commitData = [
+    ['2010-04-15', 5],
+    ['2010-05-15', 5],
+    ['2010-06-15', 5],
+    ['2010-07-15', 5],
+    ['2010-08-15', 5],
+  ];
+
+  const defaultContributor = {
+    name: 'Razputin Aquato',
+    email: 'razputin.aquato@psychonauts.com',
+    commits: 25,
+    dates: [{ name: 'Commits', data: commitData }],
+  };
+
+  const findHeader = () => wrapper.findByTestId('chart-header');
+  const findCommitCount = () => wrapper.findByTestId('commit-count');
+  const findContributorAreaChart = () => wrapper.findComponent(ContributorAreaChart);
+
+  const createWrapper = (props = {}) => {
+    mockChart = { setOption: jest.fn() };
+
+    wrapper = shallowMountExtended(IndividualChart, {
+      propsData: {
+        contributor: defaultContributor,
+        chartOptions: {},
+        zoom: {},
+        ...props,
+      },
+    });
+
+    findContributorAreaChart().vm.$emit('created', mockChart);
+  };
+
+  describe('when not zoomed', () => {
+    beforeEach(() => {
+      createWrapper();
+    });
+
+    it('shows the contributor name as the chart header', () => {
+      expect(findHeader().text()).toBe(defaultContributor.name);
+    });
+
+    it('shows the total commit count', () => {
+      const { commits, email } = defaultContributor;
+      expect(findCommitCount().text()).toBe(`${commits} commits (${email})`);
+    });
+
+    it('renders the area chart with the given options', () => {
+      expect(findContributorAreaChart().props()).toMatchObject({
+        data: defaultContributor.dates,
+        option: {},
+        height: INDIVIDUAL_CHART_HEIGHT,
+      });
+    });
+  });
+
+  describe('when zoomed', () => {
+    const zoom = {
+      startValue: new Date('2010-05-01').getTime(),
+      endValue: new Date('2010-08-01').getTime(),
+    };
+
+    beforeEach(() => {
+      createWrapper({ zoom });
+    });
+
+    it('shows only the commits for the zoomed time period', () => {
+      const { email } = defaultContributor;
+      expect(findCommitCount().text()).toBe(`15 commits (${email})`);
+    });
+
+    it('sets the dataZoom chart option', () => {
+      const { startValue, endValue } = zoom;
+      expect(mockChart.setOption).toHaveBeenCalledWith(
+        { dataZoom: { startValue, endValue, show: false } },
+        { lazyUpdate: true },
+      );
+    });
+
+    describe('when zoom is changed', () => {
+      const newZoom = {
+        startValue: new Date('2010-04-01').getTime(),
+        endValue: new Date('2010-05-01').getTime(),
+      };
+
+      beforeEach(() => {
+        wrapper.setProps({ zoom: newZoom });
+      });
+
+      it('shows only the commits for the zoomed time period', () => {
+        const { email } = defaultContributor;
+        expect(findCommitCount().text()).toBe(`5 commits (${email})`);
+      });
+
+      it('sets the dataZoom chart option', () => {
+        const { startValue, endValue } = newZoom;
+        expect(mockChart.setOption).toHaveBeenCalledWith(
+          { dataZoom: { startValue, endValue, show: false } },
+          { lazyUpdate: true },
+        );
+      });
+    });
+  });
+});
diff --git a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
index f9e3c314d025668c8d5e6d7c992e006e5e26a137..f45d173aa98447a953b2e0b255c1103b7e049a50 100644
--- a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
@@ -5,6 +5,7 @@ import {
   nSecondsAfter,
   nSecondsBefore,
   isToday,
+  isInTimePeriod,
 } from '~/lib/utils/datetime/date_calculation_utility';
 import { useFakeDate } from 'helpers/fake_date';
 
@@ -93,3 +94,21 @@ describe('getCurrentUtcDate', () => {
     expect(getCurrentUtcDate()).toEqual(new Date('2022-12-05T00:00:00.000Z'));
   });
 });
+
+describe('isInTimePeriod', () => {
+  const date = '2022-03-22T01:23:45.000Z';
+
+  it.each`
+    start                         | end                           | expected
+    ${'2022-03-21'}               | ${'2022-03-23'}               | ${true}
+    ${'2022-03-20'}               | ${'2022-03-21'}               | ${false}
+    ${'2022-03-23'}               | ${'2022-03-24'}               | ${false}
+    ${date}                       | ${'2022-03-24'}               | ${true}
+    ${'2022-03-21'}               | ${date}                       | ${true}
+    ${'2022-03-22T00:23:45.000Z'} | ${'2022-03-22T02:23:45.000Z'} | ${true}
+    ${'2022-03-22T00:23:45.000Z'} | ${'2022-03-22T00:25:45.000Z'} | ${false}
+    ${'2022-03-22T02:23:45.000Z'} | ${'2022-03-22T03:25:45.000Z'} | ${false}
+  `('returns $expected for range: $start -> $end', ({ start, end, expected }) => {
+    expect(isInTimePeriod(new Date(date), new Date(start), new Date(end))).toBe(expected);
+  });
+});