Codeigniter, timezone_menu and date_default_timezo

2019-02-03 22:04发布

问题:

I make use of Codeigniters timezone_menu which gives a drop down box of time timezones and I am wondering how are we supposed to make use of these timezones with PHPs date_default_timezone_set?

An example of codeigniters timezone is UP1. However, you can't use that with PHPs date_default_timezone_set as the string it takes in should be something like Europe/Berlin

The question is, is there a way to convert a codeigniter timezone string to a PHP one that can be accepted by the date_default_timezone_set?

回答1:

The following works for me:

// Example - timezones is part of the date helper function
// You obviously wouldn't echo it out, you would pass it in to 
// set default timezone function in PHP based on the posted data from 
// the dropdown
echo timezone_by_offset(timezones('UM5')); // ouputs 'America/Porto_Acre' which is (-5)

// And the function
function timezone_by_offset($offset) {
    $offset = ($offset+1) * 60 * 60;
    $abbrarray = timezone_abbreviations_list();

    foreach ($abbrarray as $abbr) {
        foreach ($abbr as $city) {
            if ($city['offset'] == $offset) { 
                echo($city['timezone_id']);
                return true;
            }
        }
    }
    echo "UTC";
    return false;
} 

EDIT The original function didn't exclude DST offsets. timezone_abbreviations_list() lists 2x for a timezone that has DST marked as true, for example Tasmania appears under +11 and +10. So if DST == TRUE, ignore it as part of the return listing.

//-- Function -------------------------------------------------------------------
function timezone_by_offset($offset) {
    $abbrarray = timezone_abbreviations_list();
    $offset = $offset * 60 * 60;

    foreach ($abbrarray as $abbr) {
        foreach ($abbr as $city) {
            if ($city['offset'] == $offset && $city['dst'] == FALSE) { 
                return $city['timezone_id'];                                
            }
        }
    }
    return 'UTC'; // any default value you wish
}

Some examples:

//-- Test Cases -------------------------------------------------------------------
echo timezone_by_offset(-12) . '<br/>';  
echo (date_default_timezone_set(timezone_by_offset(-12)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
// Etc/GMT+12
// Valid 

echo timezone_by_offset(-10) . '<br/>';  
echo (date_default_timezone_set(timezone_by_offset(-10)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
// America/Anchorage
// Valid

echo timezone_by_offset(-8) . '<br/>';  
echo (date_default_timezone_set(timezone_by_offset(-8)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
// Etc/GMT+8
// Valid        

echo timezone_by_offset(6) . '<br/>';  
echo (date_default_timezone_set(timezone_by_offset(6)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
// Asia/Aqtobe
// Valid        

echo timezone_by_offset(7) . '<br/>';  
echo (date_default_timezone_set(timezone_by_offset(7)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
// Indian/Christmas
// Valid


回答2:

You can get the UTC offset for one of the U(M|P)x-values by using timezones().

$offset = timezones('UP1'); // don't know the exact format returned but should be something like 1 or '+01:00'

From this point on, I think the only way is some sort of custom mapping between the offset and the PHP timezone. You could use Etc/GMT(+|-)x timezones but the problem with those will be that they do not contain any DST-transition information.

The problem in general is, that the UTC-offsets actually map to a lot of different timezones, e.g. UP1 ((UTC + 1:00) Berlin, Brussels, Copenhagen, Madrid, Paris, Rome) maps to Europe/Berlin, Europe/Brussels, Europe/Copenhagen, Europe/Madrid, Europe/Paris, Europe/Rome but also to Africa/Luanda for example. The thing now gets arbitrarily complex due to the DST-transitions that may oder may not occur in some of these timezones.

If you don't need the DST-thing, a mapping between the return value of the timezones() function and the Etc/GMT(+|-)x timezones should be OK, otherwise you cannot use the Codeigniter timezone handling at all because the mapping is not unambiguous.



回答3:

Codeigniter gives the timezone reference back, which can be used with timezones() to get the time diff and from their you can calculate the time.



回答4:

You can use the value of the timezone offset in the gmt_to_local() function for example:

//set the time offset based on the users timezone settings
$timezone = 'UM7';

$offset = timezones($timezone);
$servertime = time();

$mytime = gmt_to_local($servertime,$offset);

$time = date("M d, Y h:i A", $mytime);

//example result
//Dec 22, 2011 04:18 PM