21

あなたのためのヘッドスクラッチャー。

IPInfoDBのAPIからgeoIPデータを取得していますが、DSTを含むUTCからのタイムゾーンオフセットが返されます(現在反映されている場合)。

たとえば、私はEST(-5)に住んでいて、現在はDSTであるため、geo IP APIは-04:00オフセットとして()を返します。

DSTはひどい頭痛の種なので、これは素晴らしいことです。しかし、驚いたことに、それは別の頭痛の種を引き起こしました。

このデータをPHPにロードして、AJAXを介してアプリケーションに渡します。アプリにIPアドレスの現地時間をライブで表示したいのですが。

私はそれをすべて完全に設定しましたが、AJAXを介して渡すために現在の時間date('H');と分を取得できるように、オフセットに一致するようにPHPタイムゾーンを設定する方法を見つけようと夢中になっています。date('i');

そのオフセットに基づいて現在の時間と分を表示できる特定の関数があるかどうか、またはオフセットに基づいてタイムゾーンを設定する実用的な方法があるかどうかはわかりません(有効な場合はDSTがすでに適用されています) 。

私はこれに対する答えを見つけるためにGoogleを検索して検索してきましたが、DSTがすでに適用されているため、私が行っていることはより具体的です。

PHP.netで、トリックを実行しているように見える関数が1つ見つかりました(自分のタイムゾーンで機能し、正しい時刻を返します)が、PSTなどの他のタイムゾーンでは、オフセットが正しい場合でも、本来より1時間遅れて返されます(-07:00DSTを使用)。

関数から返されるタイムゾーンがChile/EasterIsland原因だと感じています。できれば、これは米国でのみ機能するようにしますが、世界中で機能する必要があります。

これが私が今持っている機能です。非常に厄介なコードを許してください。私はここ数時間、解決策を見つけようとしてたくさんのことをいじっています。

ほとんどの機能はオンラインで見つかりました。

function offsetToTZ($offset) {
switch((string) $offset) {
    case '-04:30' : return 'America/Caracas'; break;
    case '-03:30' : return 'Canada/Newfoundland'; break;
    case '+03:30' : return 'Asia/Tehran'; break;
    case '+04:30' : return 'Asia/Kabul'; break;
    case '+05:30' : return 'Asia/Kolkata'; break;
    case '+05:45' : return 'Asia/Kathmandu'; break;
    case '+09:30' : return 'Australia/Darwin'; break;
}
$offset = (int) str_replace(array('0',0,':00',00,'30',30,'45',45,':','+'),'', (string) $offset);

$offset = $offset*60*60;
$abbrarray = timezone_abbreviations_list(); 
foreach ($abbrarray as $abbr) { 
    foreach($abbr as $city) { 
        if($city['offset'] == $offset) { 
            return $city['timezone_id'];
        }
    }
}
return false; 
}

そこにある特定のタイムゾーンのスイッチ/ケースを含めまし:30:45。スイッチ/ケースを必要とせずにそれを含める方法があるかもしれません。

注:オフセットは、常にそのまま、+00:00または-00:00geoIPAPIから返されます。

助けや正しい方向へのポイントをいただければ幸いです。私はPHPの初心者ではありませんが、オフセットは私にとって新しい話です。ありがとう!

4

8 に答える 8

58

オフセットを秒に変換してに渡すことで、非常に簡単に実行できますtimezone_name_from_abbr

<?php
$offset = '-7:00';

// Calculate seconds from offset
list($hours, $minutes) = explode(':', $offset);
$seconds = $hours * 60 * 60 + $minutes * 60;
// Get timezone name from seconds
$tz = timezone_name_from_abbr('', $seconds, 1);
// Workaround for bug #44780
if($tz === false) $tz = timezone_name_from_abbr('', $seconds, 0);
// Set timezone
date_default_timezone_set($tz);

echo $tz . ': ' . date('r');

デモ

の 3 番目のパラメーターはtimezone_name_from_abbr、夏時間に合わせて調整するかどうかを制御します。

バグ #44780 :

timezone_name_from_abbr() は、一部のタイム ゾーン オフセットに対して false を返します。特に、GMT オフセットから -10、-36000 秒のハワイがあります。

参考文献:

于 2012-08-10T06:38:21.677 に答える
2

タイム ゾーン オフセットをタイム ゾーン識別子にマッピングすることはお勧めできません。多くのタイム ゾーンが同じオフセットを共有しています。

たとえ一国内であっても、これは問題です。米国では、中央標準時 ( America/Chicago) と東部夏時間( ) の両方America/New_Yorkで、1 年の異なる時期に -5 オフセットが使用されていることを考慮してください。

また、これらのタイム ゾーンの両方が同時に -5 を使用する場合があることも考慮してください。たとえば、UTC-5 の 2013 年 11 月 3 日日曜日の午前 1:00 は、CDT または EST のいずれかになります。-5 だけでは、それがどのタイム ゾーンであったかを区別する方法はありません。

詳細はこちら。

于 2014-08-21T17:58:57.173 に答える
0

GMT 時間も使用して、後で必要に応じて変換することができます

<?php
echo gmdate("M d Y H:i:s", mktime(0, 0, 0, 1, 1, 1998));
?>

GMT は、世界中で共通のグリニッジ標準時を指します。

于 2014-08-22T09:32:19.033 に答える