0
<?php
    $saturday = array(
        '00:00 - 01:00' => 'Nightshow',
        '01:00 - 02:00' => 'Nightshow',
        '02:00 - 03:00' => 'Nightshow',
        '03:00 - 04:00' => 'Nightshow',
        '04:00 - 05:00' => 'Nightshow',
        '05:00 - 06:00' => 'Early birds',
        '06:00 - 07:00' => 'Early birds',
        '07:00 - 08:00' => 'Cox n Crendor in the morning',
        '08:00 - 09:00' => 'Cox n Crendor in the morning',

        ...

        '23:00 - 24:00' => 'John late night'
    );


    foreach($saturday as $timeD => $show){
        if(!empty($timeD) && isset($timeD)){
            $timesplit = explode(' -', $timeD);

            if (time() > strtotime('today '. $timesplit[0]) && time() < strtotime('today '. $timesplit[1])) {

                echo $show;
            }
        }
    }
?>

こんにちは再びスタックオーバーフロー!

スケジュールを表す時刻 (24 時間形式) を含む配列があります。私がやろうとしているのは、現在どの番組が放送されているかを確認することです。上記で試したことはうまくいきませんでした - 時間が数時間ずれていることが判明したか、特定の順序であっても完全に間違っていました. 何が悪いのかわかりません。これを解決するにはどうすればよいですか?

前もって感謝します!

4

2 に答える 2

3

基本的なタイムゾーンの問題に遭遇したと思います。

タイムゾーン基本

タイムゾーンの変換はイライラするかもしれませんが、慣れればとても簡単です。

時間を扱うときは、 や などの関数にも注意する必要がstrtotime()ありdate()ます。これら 2 つの機能、タイムゾーン設定の影響を受けます。タイムゾーン設定とはdate.timezone、php.ini の値を意味します。

たとえば、 を設定date.timezone = Asia/Singaporeすると、UTC+8 タイムゾーンになります。

UTC 時刻が現在で2013-02-05 00:00:00 UTC、タイムスタンプが次のようになるとします1360022400

  • time()私にくれます1360022400
  • strtotime('2013-02-05 00:00:00')(または-28800 1359993600、または-8時間!)

strtotimeの動作に注意してください。実際に、PHP 環境が UTC+8 タイムゾーンにあるという事実を使用し、指定した日時が +8 タイムゾーンにあると見なし、UTC タイムスタンプで正しく表現するために 8 時間戻しました。ここが問題です。

解決

通常、私がすること (おそらく誰かがより良い解決策を提供できるでしょうか?) はUTC、あいまいな日時の後ろにハードアペンドし、すべてを UTC タイムゾーンで計算するように強制することです。したがって、単純にこれを行います:

strtotime('2013-02-05 00:00:00 UTC')

1360022400は、UTC 時間で正確に 00:00:00 を提供します。time()これは、 が実際の UTC タイムスタンプを返すときに時間に敏感な計算を行う場合に特に適しています。

いくつかのメモ:

  • time()タイムゾーンの設定に関係なく、常に UTC タイムスタンプを提供します。
  • strtotime()は常にタイムゾーン設定の影響を受けるため、時間に敏感な比較を行う場合は、それらがすべて UTC であることを確認してください。
  • date()同様に、タイムゾーン設定の影響を受けdate('Y-m-d H:i:s', 1360022400)ます。2013-02-05 08:00:00これを克服するために、代わりに使用します。gmdate('Y-m-d H:i:s', 1360022400)

あなたの質問

ここであなたは時間に敏感な決定を扱っているように見えるので、1 つの質問ですが、私があなたと別のタイムゾーンに住んでいる場合、あなたと同じ結果を見る必要がありますか?


私たち (私とあなた) がまったく同じ結果を表示する必要がある場合は、次のようにする必要があります。

//Let's say the timezone required for that decision made is UTC+6
$event_timezone_offset = 6 * 3600;

foreach($saturday as $timeD => $show){
  if(!empty($timeD)){ //you don't need isset here as !empty taken care of it
    list($startTime, $endTime) = explode(' - ', $timeD);
    $start = strtotime('today '.$startTime.' UTC') - $event_timezone_offset;
    $end = strtotime('today '.$endTime.' UTC') - $event_timezone_offset;
    $now = time();
    if ($start <= $now && $now < $end) { //notice the inclusive <=
        echo $show;
    }
}

行についてはstrtotime('today '.$startTime.' UTC') - $event_timezone_offset;、次の手順を実行します。

現地時間が現在で07:00 (UTC+6)、「Cox n Crendor..」と表示されているとします。

  • time()の正確な UTC タイムスタンプが得られます2013-09-21 01:00:00 UTC
  • strtotime('today 07:00 UTC')のタイムスタンプが表示されます2013-09-21 07:00:00 UTC
  • - $event_timezone_offsetすると、次の時間が得られます2013-09-21 01:00:00 UTC
  • そのif ($start <= $now)場合は true になり、'Cox n Crendor..' と表示されるはずです。

私とあなたがそれぞれのローカル タイムスタンプに基づいて異なる結果を取得する必要がある場合は、javascript を使用してユーザーのタイムゾーンを盗聴するか、バックエンド設定でタイムゾーンを設定するように依頼し、同じロジックを使用して結果を判断する必要があります。 、設定により$event_timezone_offset = $user_timezone_offset


これがあまり混乱しないことを願っていますが、これらすべての数学を扱うのは本当に楽しいです.

于 2013-09-21T12:14:09.453 に答える
1

$fake_timestamp(後でスクリプトの現在のタイムスタンプに置き換えるtime()必要があります...しかし、テストのためにそのようにする必要がありました。)

<?php


    $saturday = array(
        '00:00 - 01:00' => 'Nightshow',
        '01:00 - 02:00' => 'Nightshow',
        '02:00 - 03:00' => 'Nightshow',
        '03:00 - 04:00' => 'Nightshow',
        '04:00 - 05:00' => 'Nightshow',
        '05:00 - 06:00' => 'Early birds',
        '06:00 - 07:00' => 'Early birds',
        '07:00 - 08:00' => 'Cox n Crendor in the morning',
        '08:00 - 09:00' => 'Cox n Crendor in the morning',
        '23:00 - 24:00' => 'John late night'
    );

    //$current_day_timestamp = gettimeofday(); //bug? returns time(), not day!time
    $current_day_timestamp = strtotime('TODAY');
    //print 'Current day time: '.$current_day_timestamp.'<br />';

    //Trying to "find" Early birds 05:00-06.00, setting "current time" to 05:30
    $fake_timestamp = $current_day_timestamp + 5.5 * 3600;
    //print 'fake time: '.$fake_timestamp.'<br />';

    foreach ($saturday AS $hours => $show) {
      $hours = explode(' - ', $hours);
      $show_start = strtotime($hours[0]);
      $show_end = strtotime($hours[1]);
      if ($show_start < $fake_timestamp AND $show_end > $fake_timestamp) {
        print $show;
      }
      //print $show.'<hr />';
      //print 'show start: '.$show_start.'<br />';
      //print 'show end: '.$show_end.'<br /><br />';
    }

?>
于 2013-09-21T10:59:45.570 に答える