chunks the dataframe/series by dates

        Parameters
        ----------
        df: pandas dataframe or series
        chunk_size: str
            any valid Pandas frequency string
        func: function
            func will be applied to each `chunk` generated by the chunker.
            This function CANNOT modify the date column of the dataframe!

        Returns
        -------
        generator that produces tuples: (start date, end date,
                  chunk_size, dataframe/series)

def to_chunks(self, df, chunk_size='D', func=None, **kwargs):
        """
        chunks the dataframe/series by dates

        Parameters
        ----------
        df: pandas dataframe or series
        chunk_size: str
            any valid Pandas frequency string
        func: function
            func will be applied to each `chunk` generated by the chunker.
            This function CANNOT modify the date column of the dataframe!

        Returns
        -------
        generator that produces tuples: (start date, end date,
                  chunk_size, dataframe/series)
        """
        if 'date' in df.index.names:
            dates = df.index.get_level_values('date')
            if not df.index.is_monotonic_increasing:
                df = df.sort_index()
        elif 'date' in df.columns:
            dates = pd.DatetimeIndex(df.date)
            if not dates.is_monotonic_increasing:
                # providing support for pandas 0.16.2 to 0.20.x
                # neither sort method exists in both
                try:
                    df = df.sort_values('date')
                except AttributeError:
                    df = df.sort(columns='date')
                dates = pd.DatetimeIndex(df.date)
        else:
            raise Exception("Data must be datetime indexed or have a column named 'date'")

        period_obj = dates.to_period(chunk_size)
        period_obj_reduced = period_obj.drop_duplicates()
        count = 0
        for _, g in df.groupby(period_obj._data):
            start = period_obj_reduced[count].start_time.to_pydatetime(warn=False)
            end = period_obj_reduced[count].end_time.to_pydatetime(warn=False)
            count += 1
            if func:
                yield start, end, chunk_size, func(g)
            else:
                yield start, end, chunk_size, g