Select next row only if different from current row
You need to join the table to itself. One instance of the table to find the values of the "current" row and the second to look for the first row that the values differ.

Since the date parameter may not exist in the table, we also need a subquery (derived table, named c) to find the previous row that holds the values for the "current" date:

SELECT 
        s.* 
FROM 
        ( SELECT start_date, breakfast, lunch, snack, dinner
          FROM times
          WHERE start_date &lt;= DATE '2016-10-16'
          ORDER BY start_date DESC
          LIMIT 1 
        ) AS c        -- "current"
    JOIN
        times AS s    -- "search"
    ON
            s.start_date &gt; c.start_date
        AND 
            (s.breakfast, s.lunch, s.snack, s.dinner) 
            &lt;&gt;
            (c.breakfast, c.lunch, c.snack, c.dinner)
ORDER BY 
        s.start_date ASC 
    LIMIT 1 ;


Tested at SQLfiddle.




This part:

        (s.breakfast, s.lunch, s.snack, s.dinner) 
        &lt;&gt;
        (c.breakfast, c.lunch, c.snack, c.dinner)


is just a compact way to write:

        (  s.breakfast &lt;&gt; c.breakfast
        OR s.lunch     &lt;&gt; c.lunch
        OR s.snack     &lt;&gt; c.snack
        OR s.dinner    &lt;&gt; c.dinner
        )

I assumed that the four time columns are not nullable. If they are nullable, the above expression would need to be more complicated.