### Apache Airflow version

2.2.0 (latest released)

### Operating System

Mac

### Versions of Apache Airflow Providers

_No response_

### Deployment

Other Docker-based deployment

### Deployment details

_No response_

### What happened

Getting an exception when returning None from next_dagrun_info in a custom timetable. The timetable protocol says that when None is returned a DagRun will not happen but right now it throws an exception.

Exception:
```
Traceback (most recent call last):
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/jobs/scheduler_job.py", line 623, in _execute
    self._run_scheduler_loop()
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/jobs/scheduler_job.py", line 704, in _run_scheduler_loop
    num_queued_tis = self._do_scheduling(session)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/jobs/scheduler_job.py", line 787, in _do_scheduling
    callback_to_run = self._schedule_dag_run(dag_run, session)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/jobs/scheduler_job.py", line 1039, in _schedule_dag_run
    self._update_dag_next_dagruns(dag, dag_model, active_runs)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/jobs/scheduler_job.py", line 930, in _update_dag_next_dagruns
    data_interval = dag.get_next_data_interval(dag_model)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/models/dag.py", line 629, in get_next_data_interval
    return self.infer_automated_data_interval(dag_model.next_dagrun)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/models/dag.py", line 671, in infer_automated_data_interval
    raise ValueError(f"Not a valid timetable: {self.timetable!r}")
ValueError: Not a valid timetable: <my_timetables.workday_timetable.WorkdayTimetable object at 0x7f42b1f02430>
```

### What you expected to happen

DagRun to not happen.

### How to reproduce

Create a custom timetable and return None in next_dagrun_info after a few DagRuns are created by that timetable

### Anything else

_No response_

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

tests/models/test_dag.py
DAG('DAG', default_args={'start_date': '2019-06-01'})
    def test_dag_naive_start_end_dates_strings(self):
        DAG('DAG', default_args={'start_date': '2019-06-01', 'end_date': '2019-06-05'})
    def test_dag_start_date_propagates_to_end_date(self):
        """
        Tests that a start_date string with a timezone and an end_date string without a timezone
        are accepted and that the timezone from the start carries over the end
        This test is a little indirect, it works by setting start and end equal except for the
        timezone and then testing for equality after the DAG construction.  They'll be equal
        only if the same timezone was applied to both.
        An explicit check the `tzinfo` attributes for both are the same is an extra check.
        """
        dag = DAG(
            'DAG', default_args={'start_date': '2019-06-05T00:00:00+05:00', 'end_date': '2019-06-05T00:00:00'}
        )
        assert dag.default_args['start_date'] == dag.default_args['end_date']
        assert dag.default_args['start_date'].tzinfo == dag.default_args['end_date'].tzinfo
    def test_dag_naive_default_args_start_date(self):
        dag = DAG('DAG', default_args={'start_date': datetime.datetime(2018, 1, 1)})
        assert dag.timezone == settings.TIMEZONE
        dag = DAG('DAG', start_date=datetime.datetime(2018, 1, 1))
        assert dag.timezone == settings.TIMEZONE
    def test_dag_none_default_args_start_date(self):
        """
        Tests if a start_date of None in default_args
        works.
        """
        dag = DAG('DAG', default_args={'start_date': None})
        assert dag.timezone == settings.TIMEZONE
    def test_dag_task_priority_weight_total(self):