We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add the ability to test and sort timestamps to be monotonic in a pandas data frame
# Brief Description

Following up on #703, this issue seeks to introduce the ability to sort the timestamps in a pandas data frame monotonically

I would like to propose...

# Example API
```python
def _test_for_monotonicity(
        df: pd.DataFrame,
        column_name: str = None,
        direction: str = 'increasing'
) -> bool:
    """
    Tests input data frame for monotonicity.

    Check if the data is monotonically increasing or decreasing.
    Direction is dependent on user input.
    Defaults to increasing

    :param df: data frame to be tested for monotonicity
    :param column_name: needs to be specified if and only if the date time is not in index.
        Defaults to None.
    :param direction: specifies the direction in which monotonicity is being tested for.
        Defaults to 'increasing'
    :return: single boolean flag indicating whether the test has passed or not
    """

def sort_monotonically(
        df: pd.DataFrame,
        column_name: str = None,
        direction: str ='increasing'
) -> pd.DataFrame:
    """
    Sorts data frame monotonically.
    It assumes the data frame has an index of type pd.DateTimeIndex when index is datetime.
    If datetime is in a column, then the column is expected to be of type pd.Timestamp

    :param df: data frame to sort monotonically
    :param column_name: needs to be specified if and only if the date time is not in index.
        Defaults to None
    :param direction: specifies the direction in which monotonicity is being tested for.
        Defaults to 'increasing'
    :return: data frame with its index sorted
    """


# more examples below
# ...
```

[ENH] Adding ability to sort timestamps monotonically
Closes #707 

# PR Description

Please describe the changes proposed in the pull request:

- Adding a function that allows monotonic sorting of timestamps in data frame 

**This PR resolves #707 **

# PR Checklist
Please ensure that you have done the following:

1. [x] PR in from a fork off your branch. Do not PR from `<your_username>`:`dev`, but rather from `<your_username>`:`<feature-branch_name>`.
2. [x] If you're not on the contributors list, add yourself to `AUTHORS.rst`.
3. [x] Add a line to `CHANGELOG.rst` under the latest version header (i.e. the one that is "on deck") describing the contribution.
    - Do use some discretion here; if there are multiple PRs that are related, keep them in a single line.

## Quick Check

To do a very quick check that everything is correct, follow these steps below:

- [x] Run the command `make check` from pyjanitor's top-level directory. This will automatically run:
    - black formatting
    - flake8 checking
    - running the test suite
    - docs build

Once done, please check off the check-box above.

If `make check` does not work for you, you can execute the commands listed in the Makefile individually.

## Code Changes

<!-- If you have not made code changes, please feel free to delete this section. -->

If you are adding code changes, please ensure the following:

- [x] Ensure that you have added tests.
- [x] Run all tests (`$ pytest .`) locally on your machine.
    - [x] Check to ensure that test coverage covers the lines of code that you have added.
    - [x] Ensure that all tests pass.

## Documentation Changes
If you are adding documentation changes, please ensure the following:

- [x] Build the docs locally.
- [ ] View the docs to check that it renders correctly.

# Relevant Reviewers
- @ericmjl 
- @samukweku 

Please tag maintainers to review.

- @ericmjl


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `janitor/timeseries.py`
Content:
```
1 """
2 Time series-specific data testing and cleaning functions.
3 """
4 
5 import pandas as pd
6 import pandas_flavor as pf
7 from janitor import check
8 
9 
10 @pf.register_dataframe_method
11 def fill_missing_timestamps(
12     df: pd.DataFrame,
13     frequency: str,
14     first_time_stamp: pd.Timestamp = None,
15     last_time_stamp: pd.Timestamp = None,
16 ) -> pd.DataFrame:
17     """
18     Fill dataframe with missing timestamps based on a defined frequency.
19 
20     If timestamps are missing,
21     this function will reindex the dataframe.
22     If timestamps are not missing,
23     then the function will return the dataframe unmodified.
24     Example usage:
25     .. code-block:: python
26 
27         df = (
28             pd.DataFrame(...)
29             .fill_missing_timestamps(frequency="1H")
30         )
31 
32     :param df: Dataframe which needs to be tested for missing timestamps
33     :param frequency: frequency i.e. sampling frequency of the data.
34         Acceptable frequency strings are available
35         `here <https://pandas.pydata.org/pandas-docs/stable/>`_
36         Check offset aliases under time series in user guide
37     :param first_time_stamp: timestamp expected to start from
38         Defaults to None.
39         If no input is provided assumes the minimum value in time_series
40     :param last_time_stamp: timestamp expected to end with.
41         Defaults to None.
42         If no input is provided, assumes the maximum value in time_series
43     :returns: dataframe that has a complete set of contiguous datetimes.
44     """
45     # Check all the inputs are the correct data type
46     check("frequency", frequency, [str])
47     check("first_time_stamp", first_time_stamp, [pd.Timestamp, type(None)])
48     check("last_time_stamp", last_time_stamp, [pd.Timestamp, type(None)])
49 
50     if first_time_stamp is None:
51         first_time_stamp = df.index.min()
52     if last_time_stamp is None:
53         last_time_stamp = df.index.max()
54 
55     # Generate expected timestamps
56     expected_timestamps = pd.date_range(
57         start=first_time_stamp, end=last_time_stamp, freq=frequency
58     )
59 
60     return df.reindex(expected_timestamps)
61 
62 
63 def _get_missing_timestamps(
64     df: pd.DataFrame,
65     frequency: str,
66     first_time_stamp: pd.Timestamp = None,
67     last_time_stamp: pd.Timestamp = None,
68 ) -> pd.DataFrame:
69     """
70     Return the timestamps that are missing in a dataframe.
71 
72     This function takes in a dataframe,
73     and checks its index against a dataframe
74     that contains the expected timestamps.
75     Here, we assume that the expected timestamps
76     are going to be of a larger size
77     than the timestamps available in the input dataframe ``df``.
78 
79     If there are any missing timestamps in the input dataframe,
80     this function will return those missing timestamps
81     from the expected dataframe.
82     """
83     expected_df = df.fill_missing_timestamps(
84         frequency, first_time_stamp, last_time_stamp
85     )
86 
87     missing_timestamps = expected_df.index.difference(df.index)
88 
89     return expected_df.loc[missing_timestamps]
90
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/janitor/timeseries.py b/janitor/timeseries.py
--- a/janitor/timeseries.py
+++ b/janitor/timeseries.py
@@ -87,3 +87,58 @@
     missing_timestamps = expected_df.index.difference(df.index)
 
     return expected_df.loc[missing_timestamps]
+
+
+@pf.register_dataframe_method
+def sort_timestamps_monotonically(
+    df: pd.DataFrame, direction: str = "increasing", strict: bool = False
+) -> pd.DataFrame:
+    """
+    Sort dataframe such that index is monotonic.
+
+    If timestamps are monotonic,
+    this function will return the dataframe unmodified.
+    If timestamps are not monotonic,
+    then the function will sort the dataframe.
+
+    Example usage:
+
+    .. code-block:: python
+
+        df = (
+            pd.DataFrame(...)
+            .sort_timestamps_monotonically(direction='increasing')
+        )
+
+    :param df: Dataframe which needs to be tested for monotonicity
+    :param direction: type of monotonicity desired.
+        Acceptable arguments are:
+            1. increasing
+            2. decreasing
+    :param strict: flag to enable/disable strict monotonicity.
+        If set to True,
+        will remove duplicates in the index,
+        by retaining first occurrence of value in index.
+        If set to False,
+        will not test for duplicates in the index.
+        Defaults to False.
+    :returns: Dataframe that has monotonically increasing
+        (or decreasing) timestamps.
+    """
+    # Check all the inputs are the correct data type
+    check("df", df, [pd.DataFrame])
+    check("direction", direction, [str])
+    check("strict", strict, [bool])
+
+    # Remove duplicates if requested
+    if strict:
+        df = df[~df.index.duplicated(keep="first")]
+
+    # Sort timestamps
+    if direction == "increasing":
+        df = df.sort_index()
+    else:
+        df = df.sort_index(ascending=False)
+
+    # Return the dataframe
+    return df

{"golden_diff": "diff --git a/janitor/timeseries.py b/janitor/timeseries.py\n--- a/janitor/timeseries.py\n+++ b/janitor/timeseries.py\n@@ -87,3 +87,58 @@\n     missing_timestamps = expected_df.index.difference(df.index)\n \n     return expected_df.loc[missing_timestamps]\n+\n+\n+@pf.register_dataframe_method\n+def sort_timestamps_monotonically(\n+    df: pd.DataFrame, direction: str = \"increasing\", strict: bool = False\n+) -> pd.DataFrame:\n+    \"\"\"\n+    Sort dataframe such that index is monotonic.\n+\n+    If timestamps are monotonic,\n+    this function will return the dataframe unmodified.\n+    If timestamps are not monotonic,\n+    then the function will sort the dataframe.\n+\n+    Example usage:\n+\n+    .. code-block:: python\n+\n+        df = (\n+            pd.DataFrame(...)\n+            .sort_timestamps_monotonically(direction='increasing')\n+        )\n+\n+    :param df: Dataframe which needs to be tested for monotonicity\n+    :param direction: type of monotonicity desired.\n+        Acceptable arguments are:\n+            1. increasing\n+            2. decreasing\n+    :param strict: flag to enable/disable strict monotonicity.\n+        If set to True,\n+        will remove duplicates in the index,\n+        by retaining first occurrence of value in index.\n+        If set to False,\n+        will not test for duplicates in the index.\n+        Defaults to False.\n+    :returns: Dataframe that has monotonically increasing\n+        (or decreasing) timestamps.\n+    \"\"\"\n+    # Check all the inputs are the correct data type\n+    check(\"df\", df, [pd.DataFrame])\n+    check(\"direction\", direction, [str])\n+    check(\"strict\", strict, [bool])\n+\n+    # Remove duplicates if requested\n+    if strict:\n+        df = df[~df.index.duplicated(keep=\"first\")]\n+\n+    # Sort timestamps\n+    if direction == \"increasing\":\n+        df = df.sort_index()\n+    else:\n+        df = df.sort_index(ascending=False)\n+\n+    # Return the dataframe\n+    return df\n", "issue": "Add the ability to test and sort timestamps to be monotonic in a pandas data frame\n# Brief Description\r\n\r\nFollowing up on #703, this issue seeks to introduce the ability to sort the timestamps in a pandas data frame monotonically\r\n\r\nI would like to propose...\r\n\r\n# Example API\r\n```python\r\ndef _test_for_monotonicity(\r\n        df: pd.DataFrame,\r\n        column_name: str = None,\r\n        direction: str = 'increasing'\r\n) -> bool:\r\n    \"\"\"\r\n    Tests input data frame for monotonicity.\r\n\r\n    Check if the data is monotonically increasing or decreasing.\r\n    Direction is dependent on user input.\r\n    Defaults to increasing\r\n\r\n    :param df: data frame to be tested for monotonicity\r\n    :param column_name: needs to be specified if and only if the date time is not in index.\r\n        Defaults to None.\r\n    :param direction: specifies the direction in which monotonicity is being tested for.\r\n        Defaults to 'increasing'\r\n    :return: single boolean flag indicating whether the test has passed or not\r\n    \"\"\"\r\n\r\ndef sort_monotonically(\r\n        df: pd.DataFrame,\r\n        column_name: str = None,\r\n        direction: str ='increasing'\r\n) -> pd.DataFrame:\r\n    \"\"\"\r\n    Sorts data frame monotonically.\r\n    It assumes the data frame has an index of type pd.DateTimeIndex when index is datetime.\r\n    If datetime is in a column, then the column is expected to be of type pd.Timestamp\r\n\r\n    :param df: data frame to sort monotonically\r\n    :param column_name: needs to be specified if and only if the date time is not in index.\r\n        Defaults to None\r\n    :param direction: specifies the direction in which monotonicity is being tested for.\r\n        Defaults to 'increasing'\r\n    :return: data frame with its index sorted\r\n    \"\"\"\r\n\r\n\r\n# more examples below\r\n# ...\r\n```\r\n\n[ENH] Adding ability to sort timestamps monotonically\nCloses #707 \r\n\r\n# PR Description\r\n\r\nPlease describe the changes proposed in the pull request:\r\n\r\n- Adding a function that allows monotonic sorting of timestamps in data frame \r\n\r\n**This PR resolves #707 **\r\n\r\n# PR Checklist\r\nPlease ensure that you have done the following:\r\n\r\n1. [x] PR in from a fork off your branch. Do not PR from `<your_username>`:`dev`, but rather from `<your_username>`:`<feature-branch_name>`.\r\n2. [x] If you're not on the contributors list, add yourself to `AUTHORS.rst`.\r\n3. [x] Add a line to `CHANGELOG.rst` under the latest version header (i.e. the one that is \"on deck\") describing the contribution.\r\n    - Do use some discretion here; if there are multiple PRs that are related, keep them in a single line.\r\n\r\n## Quick Check\r\n\r\nTo do a very quick check that everything is correct, follow these steps below:\r\n\r\n- [x] Run the command `make check` from pyjanitor's top-level directory. This will automatically run:\r\n    - black formatting\r\n    - flake8 checking\r\n    - running the test suite\r\n    - docs build\r\n\r\nOnce done, please check off the check-box above.\r\n\r\nIf `make check` does not work for you, you can execute the commands listed in the Makefile individually.\r\n\r\n## Code Changes\r\n\r\n<!-- If you have not made code changes, please feel free to delete this section. -->\r\n\r\nIf you are adding code changes, please ensure the following:\r\n\r\n- [x] Ensure that you have added tests.\r\n- [x] Run all tests (`$ pytest .`) locally on your machine.\r\n    - [x] Check to ensure that test coverage covers the lines of code that you have added.\r\n    - [x] Ensure that all tests pass.\r\n\r\n## Documentation Changes\r\nIf you are adding documentation changes, please ensure the following:\r\n\r\n- [x] Build the docs locally.\r\n- [ ] View the docs to check that it renders correctly.\r\n\r\n# Relevant Reviewers\r\n- @ericmjl \r\n- @samukweku \r\n\r\nPlease tag maintainers to review.\r\n\r\n- @ericmjl\r\n\n", "before_files": [{"content": "\"\"\"\nTime series-specific data testing and cleaning functions.\n\"\"\"\n\nimport pandas as pd\nimport pandas_flavor as pf\nfrom janitor import check\n\n\n@pf.register_dataframe_method\ndef fill_missing_timestamps(\n    df: pd.DataFrame,\n    frequency: str,\n    first_time_stamp: pd.Timestamp = None,\n    last_time_stamp: pd.Timestamp = None,\n) -> pd.DataFrame:\n    \"\"\"\n    Fill dataframe with missing timestamps based on a defined frequency.\n\n    If timestamps are missing,\n    this function will reindex the dataframe.\n    If timestamps are not missing,\n    then the function will return the dataframe unmodified.\n    Example usage:\n    .. code-block:: python\n\n        df = (\n            pd.DataFrame(...)\n            .fill_missing_timestamps(frequency=\"1H\")\n        )\n\n    :param df: Dataframe which needs to be tested for missing timestamps\n    :param frequency: frequency i.e. sampling frequency of the data.\n        Acceptable frequency strings are available\n        `here <https://pandas.pydata.org/pandas-docs/stable/>`_\n        Check offset aliases under time series in user guide\n    :param first_time_stamp: timestamp expected to start from\n        Defaults to None.\n        If no input is provided assumes the minimum value in time_series\n    :param last_time_stamp: timestamp expected to end with.\n        Defaults to None.\n        If no input is provided, assumes the maximum value in time_series\n    :returns: dataframe that has a complete set of contiguous datetimes.\n    \"\"\"\n    # Check all the inputs are the correct data type\n    check(\"frequency\", frequency, [str])\n    check(\"first_time_stamp\", first_time_stamp, [pd.Timestamp, type(None)])\n    check(\"last_time_stamp\", last_time_stamp, [pd.Timestamp, type(None)])\n\n    if first_time_stamp is None:\n        first_time_stamp = df.index.min()\n    if last_time_stamp is None:\n        last_time_stamp = df.index.max()\n\n    # Generate expected timestamps\n    expected_timestamps = pd.date_range(\n        start=first_time_stamp, end=last_time_stamp, freq=frequency\n    )\n\n    return df.reindex(expected_timestamps)\n\n\ndef _get_missing_timestamps(\n    df: pd.DataFrame,\n    frequency: str,\n    first_time_stamp: pd.Timestamp = None,\n    last_time_stamp: pd.Timestamp = None,\n) -> pd.DataFrame:\n    \"\"\"\n    Return the timestamps that are missing in a dataframe.\n\n    This function takes in a dataframe,\n    and checks its index against a dataframe\n    that contains the expected timestamps.\n    Here, we assume that the expected timestamps\n    are going to be of a larger size\n    than the timestamps available in the input dataframe ``df``.\n\n    If there are any missing timestamps in the input dataframe,\n    this function will return those missing timestamps\n    from the expected dataframe.\n    \"\"\"\n    expected_df = df.fill_missing_timestamps(\n        frequency, first_time_stamp, last_time_stamp\n    )\n\n    missing_timestamps = expected_df.index.difference(df.index)\n\n    return expected_df.loc[missing_timestamps]\n", "path": "janitor/timeseries.py"}], "after_files": [{"content": "\"\"\"\nTime series-specific data testing and cleaning functions.\n\"\"\"\n\nimport pandas as pd\nimport pandas_flavor as pf\nfrom janitor import check\n\n\n@pf.register_dataframe_method\ndef fill_missing_timestamps(\n    df: pd.DataFrame,\n    frequency: str,\n    first_time_stamp: pd.Timestamp = None,\n    last_time_stamp: pd.Timestamp = None,\n) -> pd.DataFrame:\n    \"\"\"\n    Fill dataframe with missing timestamps based on a defined frequency.\n\n    If timestamps are missing,\n    this function will reindex the dataframe.\n    If timestamps are not missing,\n    then the function will return the dataframe unmodified.\n    Example usage:\n    .. code-block:: python\n\n        df = (\n            pd.DataFrame(...)\n            .fill_missing_timestamps(frequency=\"1H\")\n        )\n\n    :param df: Dataframe which needs to be tested for missing timestamps\n    :param frequency: frequency i.e. sampling frequency of the data.\n        Acceptable frequency strings are available\n        `here <https://pandas.pydata.org/pandas-docs/stable/>`_\n        Check offset aliases under time series in user guide\n    :param first_time_stamp: timestamp expected to start from\n        Defaults to None.\n        If no input is provided assumes the minimum value in time_series\n    :param last_time_stamp: timestamp expected to end with.\n        Defaults to None.\n        If no input is provided, assumes the maximum value in time_series\n    :returns: dataframe that has a complete set of contiguous datetimes.\n    \"\"\"\n    # Check all the inputs are the correct data type\n    check(\"frequency\", frequency, [str])\n    check(\"first_time_stamp\", first_time_stamp, [pd.Timestamp, type(None)])\n    check(\"last_time_stamp\", last_time_stamp, [pd.Timestamp, type(None)])\n\n    if first_time_stamp is None:\n        first_time_stamp = df.index.min()\n    if last_time_stamp is None:\n        last_time_stamp = df.index.max()\n\n    # Generate expected timestamps\n    expected_timestamps = pd.date_range(\n        start=first_time_stamp, end=last_time_stamp, freq=frequency\n    )\n\n    return df.reindex(expected_timestamps)\n\n\ndef _get_missing_timestamps(\n    df: pd.DataFrame,\n    frequency: str,\n    first_time_stamp: pd.Timestamp = None,\n    last_time_stamp: pd.Timestamp = None,\n) -> pd.DataFrame:\n    \"\"\"\n    Return the timestamps that are missing in a dataframe.\n\n    This function takes in a dataframe,\n    and checks its index against a dataframe\n    that contains the expected timestamps.\n    Here, we assume that the expected timestamps\n    are going to be of a larger size\n    than the timestamps available in the input dataframe ``df``.\n\n    If there are any missing timestamps in the input dataframe,\n    this function will return those missing timestamps\n    from the expected dataframe.\n    \"\"\"\n    expected_df = df.fill_missing_timestamps(\n        frequency, first_time_stamp, last_time_stamp\n    )\n\n    missing_timestamps = expected_df.index.difference(df.index)\n\n    return expected_df.loc[missing_timestamps]\n\n\n@pf.register_dataframe_method\ndef sort_timestamps_monotonically(\n    df: pd.DataFrame, direction: str = \"increasing\", strict: bool = False\n) -> pd.DataFrame:\n    \"\"\"\n    Sort dataframe such that index is monotonic.\n\n    If timestamps are monotonic,\n    this function will return the dataframe unmodified.\n    If timestamps are not monotonic,\n    then the function will sort the dataframe.\n\n    Example usage:\n\n    .. code-block:: python\n\n        df = (\n            pd.DataFrame(...)\n            .sort_timestamps_monotonically(direction='increasing')\n        )\n\n    :param df: Dataframe which needs to be tested for monotonicity\n    :param direction: type of monotonicity desired.\n        Acceptable arguments are:\n            1. increasing\n            2. decreasing\n    :param strict: flag to enable/disable strict monotonicity.\n        If set to True,\n        will remove duplicates in the index,\n        by retaining first occurrence of value in index.\n        If set to False,\n        will not test for duplicates in the index.\n        Defaults to False.\n    :returns: Dataframe that has monotonically increasing\n        (or decreasing) timestamps.\n    \"\"\"\n    # Check all the inputs are the correct data type\n    check(\"df\", df, [pd.DataFrame])\n    check(\"direction\", direction, [str])\n    check(\"strict\", strict, [bool])\n\n    # Remove duplicates if requested\n    if strict:\n        df = df[~df.index.duplicated(keep=\"first\")]\n\n    # Sort timestamps\n    if direction == \"increasing\":\n        df = df.sort_index()\n    else:\n        df = df.sort_index(ascending=False)\n\n    # Return the dataframe\n    return df\n", "path": "janitor/timeseries.py"}]}