Добавление дней в метку времени

Давая дату начала, я добавляю четыре раза семь дней, чтобы получить 5 разных дат, разделенных ровно на неделю каждый.

//$date = '28-10-2010';
$timestamp = mktime( 0, 0, 0, 10, 01, 2010 );
echo "Date=".date( 'd-m-Y', $timestamp )."<br>";

$timestamp += (60*60*24*7);
echo "Date=".date( 'd-m-Y', $timestamp )."<br>";

$timestamp += (60*60*24*7);
echo "Date=".date( 'd-m-Y', $timestamp )."<br>";

$timestamp += (60*60*24*7);
echo "Date=".date( 'd-m-Y', $timestamp )."<br>";

$timestamp += (60*60*24*7);
echo "Date=".date( 'd-m-Y', $timestamp )."<br>";

Код выводит это:

Date=01-10-2010 Friday
Date=08-10-2010 Friday
Date=15-10-2010 Friday
Date=22-10-2010 Friday
Date=29-10-2010 Friday

Которое я знаю, это правильно. Но посмотрите, что произойдет, пройдя 2010-10-31 и 2010-11-01.

$timestamp = mktime (0, 0, 0, 10, 28, 2010);  [...]

Любопытно, что он выводит это:

Date=28-10-2010 Thursday
Date=03-11-2010 Wednesday
Date=10-11-2010 Wednesday
Date=17-11-2010 Wednesday
Date=24-11-2010 Wednesday

Что происходит? Вторая дата должна быть 04-11-2010! Кроме того, я видел, что этот "провал" происходит каждые десять лет! Связано ли это с летним временем? Если да, то как это решить? Есть ли что-то, что я пропускаю?

Изменить: Хорошо, я отобразил время, просто чтобы узнать, что произойдет, и это то, что я получил сейчас:

Date=28-10-2010 Thursday :: 00:00:00
Date=03-11-2010 Wednesday :: 23:00:00
Date=10-11-2010 Wednesday :: 23:00:00
Date=17-11-2010 Wednesday :: 23:00:00
Date=24-11-2010 Wednesday :: 23:00:00

Кажется, что-то связано со временем, что-то происходит в 2010-11-31...

Ответ 1

Никогда используйте математику, например, 60 * 60 * 24 * 7 для добавления/вычитания дней (из-за экономии дневного света) вместо strtotime или mktime:

$timestamp = strtotime('+7 days', $timestamp);

// Or something like this (it OK to have day parameter <= 0 or > 31)
$timestamp = mktime(0, 0, 0, $month, $day + 7, $year);

Ваш пример будет более очевидным, если вы также выведете время:

$timestamp = mktime(0, 0, 0, 10, 28, 2010);
echo date('Y-m-d H:i:s', $timestamp) . "\n";

$timestamp += 60*60*24*7;
echo date('Y-m-d H:i:s', $timestamp) . "\n";

Вывод:

2010-10-28 00:00:00
2010-11-03 23:00:00

Здесь у вас 2010-11-03 23:00:00 вместо 2010-11-04 00:00:00, потому что один из дней (31 октября) составляет 25, а не 24.

Ответ 2

Похоже, вы перешли на экономию времени или обратно.

Время POSIX (временная метка) - это всегда UTC, в то время как местное время UTC + X X может меняться с даты на дату в соответствии с экономией времени.

Ответ 3

Кажется, что это связано с часовым поясом /DST.

Добавление

date_default_timezone_set('UTC');

поскольку первая строка решает проблему (поскольку вы больше не используете какие-либо настройки DST).

Ответ 4

Я считаю, что это имеет какое-то отношение к летнему времени, потому что сегмент "времени" вашей метки времени установлен до полуночи на точке, но когда заканчивается дневная экономия, мы возвращаемся на час - который остается на прошлой неделе ( в 11:00).

Если вы добавите 2 часа к исходной строке, вы получите следующее:

$timestamp = mktime( 2, 0, 0, 10, 01, 2010 );

и, следовательно, начинать с 2 утра, а не в полночь... он работает.

Ответ 5

Я никогда не пойму, почему люди используют эту ужасную функцию mktime.

Если вы еще на PHP5.3, вам может потребоваться использовать

$period = new DatePeriod(
    new DateTime('28-10-2010'),
    DateInterval::createFromDateString('1 week'),
    4);

foreach ( $period as $dt ) {
  echo $dt->format( "l Y-m-d H:i:s\n" );
}

Без PHP5.3 вы все равно можете использовать

for($i=0; $i<=4; $i++) {
    echo date('Y-m-d', strtotime("+$i weeks 28-10-2010")), PHP_EOL;
}

Вопросы DateTime довольно распространены в SO, поэтому вы можете найти интересные случаи при поиске.

Ответ 6

У меня был большой успех в этой методологии для добавления дней, хотя я не тестировал ваш формат:

$date = The value of the database from your query
$daysahead = The number of days ahead you want to calculate
$final_date = date("m/d/Y", strtotime($date) + (86400 * $daysahead));

echo $final_date;

Ответ 7

В случае, если кому-то это нужно, точно так же, как я ссылаюсь на сайт: Сегодня, текущее время, Y-m-d H: i: s, плюс +7 Days. ИЛИ вы можете добавить +3 месяца и т.д.

$timestamp=strtotime("+7 Days");
$nowtime =  date('Y-m-d H:i:s', $timestamp);