PHP: каждые X недель для календаря, повторяющихся событий - PullRequest
0 голосов
/ 30 сентября 2011

Я пытаюсь получить каждые X дней с определенной даты для календаря.Я думаю, что у меня логика до некоторой степени, но для небольшого окна дат я получаю неожиданные результаты.

Мой код ниже взят из моего проекта:

$start_time = 1345935600; //Sept 25th 2011; 
$end_time = 1355011200; //Dec 9th 2011;

$sStartDate = date("Y-m-d", $start_time) . " " . date("H:i:s", strtotime("00:00:00"));
$sEndDate = date("Y-m-d", $end_time) . " " . date("H:i:s", strtotime("00:00:00"));
$sCurrentDate = $sStartDate; 

while($sCurrentDate < $sEndDate)
{                                       
    $t_date = strtotime($sCurrentDate);
    $s_date = strtotime(date("Y-m-d", strtotime("08/30/2011")));

    $recurs_every = 60 * 60 * 24 * 2; //occurs every 2 days

    echo date("Y-m-d H:i:s", $t_date) . " " . date("Y-m-d H:i:s", $s_date) . " " . (($t_date - $s_date) % $recurs_every) . " " . $recurs_every . "<BR>" ;   

    $sCurrentDate = date("Y-m-d", strtotime("+1 day", strtotime($sCurrentDate)));                                               
}

Выходы (текущиедата - дата начала - модульная):

2011-09-25 00:00:00 2011-08-30 00:00:00 0
2011-09-26 00:00:00 2011-08-30 00:00:00 86400
....
2012-10-27 00:00:00 2011-08-30 00:00:00 0
2012-10-28 00:00:00 2011-08-30 00:00:00 86400
2012-10-29 00:00:00 2011-08-30 00:00:00 3600
2012-10-30 00:00:00 2011-08-30 00:00:00 90000
2012-10-31 00:00:00 2011-08-30 00:00:00 3600
2012-11-01 00:00:00 2011-08-30 00:00:00 90000
2012-11-02 00:00:00 2011-08-30 00:00:00 3600
2012-11-03 00:00:00 2011-08-30 00:00:00 90000
2012-11-04 00:00:00 2011-08-30 00:00:00 3600
2012-11-05 00:00:00 2011-08-30 00:00:00 90000

Последние несколько строк - это проблема для меня.

3600 - один час, и я не знаю, откуда это.Странно то, что вперед 26 марта 2012 года, и он снова начинает работать, но такая же ошибка возникает 29 октября 2012 года ...

Я занимался этим несколько часов и не могу понять,Любая помощь очень ценится!

Спасибо

Ответы [ 2 ]

0 голосов
/ 01 октября 2011

Я дал вам ответ на вопрос и усилия. В конце концов, я переосмыслил и сделал больше поисков, и это то, что я придумал.

$start_time = 1316905200;
$end_time = 1320537600;

$sStartDate = date("Y-m-d", $start_time);
$sEndDate = date("Y-m-d", $end_time);

$sStartDate = new DateTime($sStartDate);
$sEndDate = new DateTime($sEndDate);

$sCurrentDate = $sStartDate; 
$recurs_every = 60 * 60 * 24 * 2; //occurs every 2 days

while($sCurrentDate->format('U') < $sEndDate->format('U'))
{       
    $s_date = new DateTime("08/30/2011");

    echo $sCurrentDate->format('Y-m-d') . " " . $s_date->format('Y-m-d') . " " . ceil(($sCurrentDate->format('U') - $s_date->format('U') - (chkTransitions($sCurrentDate->format('U')) == 'GMT' ? 3600 : 0)) % $recurs_every) . "<BR>";

    $sCurrentDate->add(new DateInterval('P1D'));    
}

function chkTransitions($dt)
{
    $timezone = new DateTimeZone("Europe/London");
    $transitions = $timezone->getTransitions($dt, $dt);

    $offset = $transitions[0]['offset']; 
    $abbr = $transitions[0]['abbr']; 

    return $abbr;
}
0 голосов
/ 30 сентября 2011

В некоторых странах есть летнее и зимнее время, когда часы переводятся в один час (@ 27 марта и 30 окт). Поэтому разница в один час.

-> http://en.wikipedia.org/wiki/Daylight_saving_time

Пример:

<?

error_reporting(E_ALL);

$start_time = 1345935600; //Sept 25th 2011; 
$end_time = 1355011200; //Dec 9th 2011;

$sStartDate = date("Y-m-d", $start_time) . " " . date("H:i:s", strtotime("00:00:00"));
$sEndDate = date("Y-m-d", $end_time) . " " . date("H:i:s", strtotime("00:00:00"));
$sCurrentDate = $sStartDate; 

$lastDate = 0;
$corr = 0;

while($sCurrentDate < $sEndDate)
{                                       
    $t_date = strtotime($sCurrentDate);
    $s_date = strtotime(date("Y-m-d", strtotime("08/30/2011")));

    $recurs_every = 60 * 60 * 24 * 2; //occurs every 2 days

    echo date("Y-m-d H:i:s", $t_date) . " " . date("Y-m-d H:i:s", $s_date) . " " . (($t_date - $s_date + $corr) % $recurs_every) . " " . $recurs_every . "<BR>" ;   

    $lastDate = strtotime($sCurrentDate);
    $sCurrentDate = date("Y-m-d", strtotime("+1 day", strtotime($sCurrentDate)));             

    if(strtotime($sCurrentDate) - $lastDate != 60 * 60 * 24) {
        $corr -= strtotime($sCurrentDate) - $lastDate - 60 * 60 * 24;
    }
}

?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...