No, this is expected behavior. Your solution with setTimezone() is the proper way to handle it.
When using a Unix timestamp with DateTime (like @1718607600), PHP ignores both the default timezone and any timezone passed to the constructor. That's why your first snippet shows +00:00 - it's forced to UTC.
The fix is simple: Create your timestamp in UTC, then convert it to your timezone using setTimezone() right after:
$row->created = (new DateTime('@' . $row->created)) ->setTimezone(new DateTimeZone(config('app.timezone')));
Your second snippet already does this correctly. Unix timestamps are UTC-based, so you always need this explicit conversion to show them in local time.