Getting client timezone name to use with PHP date_default_timezone_set()
On the javascript side:


I am not seeing any value in creating the string format for the offset that you are creating, as you just end up spending more code in PHP trying to get to a usable format. This is all more work than necessary. Consider keeping offset in minute-based javascript format or converting to second-based format.
You seem to use your cookie management library inconsistently here.  You write using a jQuery extension like $.cookie() while reading the actual cookie string from document. Why not use your library for both (or does it not support that?)  Also, not sure what you what your library does with expires: null. Hopefully this set to session-length cookie?


On PHP side:

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 can help move you away from the concept of resetting your default system timezone, which I don't think you want to overwrite here, but rather use as fallback.  There may be other parts of your code that do things like insert records into database datetime fields or something like that where you want to use a consistent system time, not the end users timezone.  I don't think you have an appropriate use case for changing this setting (at least from the context shown).

Let's show an example of how this might look using DateTimeZone:

$system_tz = date_default_timezone_get();

// assume $_COOKIE['hp_time_offset'] contains a minute based offset like
// output by javascript Date().getTimezoneOffset()
if (!empty($_COOKIE('hp_time_offset') &amp;&amp;
    is_numeric($_COOKIE['hp_time_offset'])) {

    $offset_min = (int)$_COOKIE['hp_time_offset'];
    $offset_sec = $offset_min * 60;
    // is current system in daylight savings?
    $is_dst = (int)date('I');
    // get timezone name
    $tz = timezone_name_from_abbr('', $offset_sec, $is_dst);
    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-&gt;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.