How to Schedule Cronjobs for start of every month and year

If you need it on the first day of the month, you should still run this daily. Just be sure to check if “today” is the first of the month. Even your “first day of the year” would be executed if it is the first day of the month.

You can check this with the following:

$dtFirst = new DateTime('first day of this month');
$dtToday = new DateTime('today');

$interval = $dtToday->diff($dtFirst);

// format('%a') produces total 'days' from DateTime::diff()
if ($interval->format('%a') == '0'){
   // Do your stuff here...
}

Doing this check daily will avoid issues with leap years, etc., without significant impact to your server.

I would also recommend you use a system cron to replace the WP Cron, to ensure you get a proper execution. WP Cron is too dependant on user activity.