Block caching based on time
On this time scale, a cache TTL probably isn't the way to go, since the age is counted from creation time without respecting calendar years. You know exactly when the cache should expire (midnight on New Years') so instead of giving it a one-year maximum age it may be better to just actively clean it with a cron.

To avoid throwing away the entire cache (which can lead to significant performance degradation on some sites), you can use a cache tag: 

$render['#cache']['tags'] = ['date:year'];


And then, in the annual cron, just invalidate the date:year cache tag like this:

function custom_cron() {
  $last = \Drupal::state()-&gt;get('system.cron_last');
  if (date('Y') !== date('Y', $last)) {
    Cache::invalidateTags(['date:year']);
  }
}


(Note that this solution does the absolute minimum of cache invalidation. If you find that your site performs well even if you completely purge the cache every day, that's fine.)