Как уже упоминалось в RiggsFolly, проблема может быть в летнем времени. Чтобы PHP не делал странных вещей, сделайте все изменения за один шаг. Таким образом, вы пропускаете часть анализа строки до даты, форматируете ее обратно в строку и снова анализируете ее как дату:
$txtstart_date = '2019-03-31';
$day_time = '10:00';
$hours = '0';
$minutes = '15';
$datetime = $txtstart_date . ' ' . $day_time;
echo DateTime::createFromFormat('Y-m-d H:i', $datetime)
->modify('+' . $hours . ' hour')
->modify('+' . $minutes . ' minute')
->format('Y-m-d H:i:s');
Если вам нужна одна и та же дата дважды, чтобы ее можно было изменить, просто клонируйте ее:
$baseTime = DateTime::createFromFormat('Y-m-d H:i', $datetime);
$toBeModified = clone $baseTime;
echo $baseTime->format('Y-m-d H:i:s') . PHP_EOL;
echo $toBeModified
->modify('+' . $hours . ' hour')
->modify('+' . $minutes . ' minute')
->format('Y-m-d H:i:s') . PHP_EOL;
Также возможно изменить используемый часовой пояс объекта DateTime (который может быть очень полезен в контексте базы данных, когда даты, хранящиеся в базе данных, являются utc):
echo DateTime::createFromFormat('Y-m-d H:i', $datetime, new DateTimeZone('Europe/London'))
->setTimezone(new DateTimeZone('UTC'))
->format('Y-m-d H:i:s');