<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _do_date_facets(results, date_facets):
 """ Private method that facets a document by date ranges Required arguments: `results` -- A list SearchResults to facet `date_facets` -- A dictionary containing facet parameters: nb., gap must be one of the following: year|month|day|hour|minute|second For each date facet field in `date_facets`, generates a list of date ranges (from `start_date` to `end_date` by `gap_by`) then iterates through `results` and tallies the count for each date_facet. Returns a dictionary of date facets (fields) containing a list with entries for each range and a count of documents matching the range. eg. { 'pub_date': [ (datetime.datetime(2009, 1, 1, 0, 0), 5), (datetime.datetime(2009, 2, 1, 0, 0), 0), (datetime.datetime(2009, 3, 1, 0, 0), 0), (datetime.datetime(2008, 4, 1, 0, 0), 1), (datetime.datetime(2008, 5, 1, 0, 0), 2), ], } """

        def next_datetime(previous, gap_value, gap_type):
            year = previous.year
            month = previous.month

            if gap_type == 'year':
                next = previous.replace(year=year + gap_value)
            elif gap_type == 'month':
                if month + gap_value <= 12:
                    next = previous.replace(month=month + gap_value)
                else:
                    next = previous.replace(
                        month=((month + gap_value) % 12),
                        year=(year + (month + gap_value) // 12)
                    )
            elif gap_type == 'day':
                next = previous + datetime.timedelta(days=gap_value)
            elif gap_type == 'hour':
                return previous + datetime.timedelta(hours=gap_value)
            elif gap_type == 'minute':
                next = previous + datetime.timedelta(minutes=gap_value)
            elif gap_type == 'second':
                next = previous + datetime.timedelta(seconds=gap_value)
            else:
                raise TypeError('\'gap_by\' must be '
                                '{second, minute, day, month, year}')
            return next

        facet_dict = {}

        for date_facet, facet_params in list(date_facets.items()):
            gap_type = facet_params.get('gap_by')
            gap_value = facet_params.get('gap_amount', 1)
            date_range = facet_params['start_date']

            # construct the bins of the histogram
            facet_list = []
            while date_range < facet_params['end_date']:
                facet_list.append((date_range, 0))
                date_range = next_datetime(date_range, gap_value, gap_type)

            facet_list = sorted(facet_list, key=lambda x: x[0], reverse=True)

            for result in results:
                result_date = getattr(result, date_facet)

                # convert date to datetime
                if not isinstance(result_date, datetime.datetime):
                    result_date = datetime.datetime(result_date.year,
                                                    result_date.month,
                                                    result_date.day)

                # ignore results outside the boundaries.
                if facet_list[0][0] < result_date < facet_list[-1][0]:
                    continue

                # populate the histogram by putting the result on the right bin.
                for n, facet_date in enumerate(facet_list):
                    if result_date > facet_date[0]:
                        # equal to facet_list[n][1] += 1, but for a tuple
                        facet_list[n] = (facet_list[n][0], (facet_list[n][1] + 1))
                        break  # bin found; go to next result

            facet_dict[date_facet] = facet_list

        return facet_dict