<?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;
}
}
}
?>
再次问好Stackoverflow!
我有一个数组,包含代表日程安排的一天中的某些时间(24小时格式)。我正在尝试做的是检查目前正在播出的节目。我上面尝试的东西不起作用 - 时间结果是几个小时或者他们完全错了,甚至没有按照一定的顺序。我不明白什么是错的。我该如何解决这个问题?
提前致谢!
答案 0 :(得分:3)
我相信你遇到了一些基本的时区问题。
时区转换可能令人沮丧,但一旦你习惯了它,它就会非常直接。
当我们处理时间时,我们还需要注意strtotime()
和date()
等功能。这两个函数 受时区设置的影响。当我说时区设置时,我的意思是你的php.ini中的值date.timezone
。
例如,我设置date.timezone = Asia/Singapore
,它是UTC + 8时区:
我们说UTC时间现在是2013-02-05 00:00:00 UTC
,时间戳应该是1360022400
:
time()
会给我1360022400
strtotime('2013-02-05 00:00:00')
会给我1359993600
(或-28800,或-8小时!)注意strtotime
的行为方式?它实际上使用这个事实,PHP环境是UTC + 8时区,并认为你指定的日期时间是+8时区,因此它为你推迟了8个小时,以正确表示它以UTC时间戳。这就是问题所在。
通常,我会做什么(也许某人可以提供更好的解决方案?)是在模糊的日期时间后面添加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)
。所以,既然你似乎在处理时间敏感的决定,一个问题,如果我与你住在不同的时区,我是否需要看到与你相同的结果?
如果我们(我和你)需要看到完全相同的结果,那么你应该这样做:
//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()
将为您提供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)
将是真的,你应该看到'Cox n Crendor ..'如果我和你需要根据我们各自的本地时间戳得到不同的结果,那么你需要sniff user's timezone using javascript,或者要求他们通过一些后端设置设置时区,并使用相同的逻辑来通过设置$event_timezone_offset = $user_timezone_offset
确定结果。
我希望这不会太混乱,但处理所有这些数学真的很有趣。
答案 1 :(得分: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 />';
}
?>