I would strongly consider using PHP's `DateTime` and related classes (in this case specifically, `DateTimeZone`) rather than the procedural `date_*` functions.  Over time I think you will find them much more powerful and flexible in usage.  This also moves you away from the concept of resetting you default system timezone, which I don't think you want to overwrite here, but rather us as fallback.

Let's show an example usage:

    // assume $_COOKIE['hp_time_offset'] contains string like 'America/New York'
    // list of acceptable strings is at http://php.net/manual/en/timezones.php
    
    $system_tz = date_default_timezone_get();
    if(!empty($_COOKIE('hp_time_offset')) {
       $tz = $_COOKIE['hp_time_offset'];
        try {
            $date_timezone = new DateTimeZone($tz);
        } catch (Exception $e) {
            error_log('Invalid timezone string of "' . $tz . '" passed from cookie.');
            $tz = $system_tz;
        }
    }
    
    if(empty($timezone)) {
        // I am not wrapping this in try-catch as if there is a failure here
        // I don't know what you want to do to recover (as this should not happen).
        // Feel free to catch if needed for your implementation
        $date_timezone = new DateTimeZone($tz);
    }
    
    return $date_timezone;
    // or if you just want to return the timezone string
    // return $date_timezone->getName();

This proposed functionality gives you a valid `DateTimeZone` object representing either the cookie-derived timezone or, as a fallback, the system timezone.  You can use this object to instantiate any `DateTime` object you may need on your system with those objects automatically taking on the expected timezone behavior.