Ответы пользователя по тегу Работа с датой/временем
  • Сколько дней в пересечении двух дат?

    Lobotomist
    @Lobotomist
    Software Developer
    Пересечение двух диапазонов дат получить довольно просто - это разница между самым поздним началом и самым ранним концом этих периодов.

    /**
     * Предполагается, что dateStart <= dateEnd. Если это не гарантируется, нужно их привести к такому виду внутри функции.
     */
    function getIntersectDays(DateTime $dateStart1, DateTime $dateEnd1, DateTime $dateStart2, DateTime $dateEnd2) : int {
        $intersectionEnd = min($dateEnd1, $dateEnd2);
        $intersectionStart = max($dateStart1, $dateStart2);
    
        if ($intersectionStart >= $intersectionEnd) return 0;
    
        return (int)$intersectionStart->diff($intersectionEnd)->format('%a');
    }
    Ответ написан
  • Как узнать timestamp полуночи после смены часового пояса?

    Lobotomist
    @Lobotomist
    Software Developer
    Дело в том, что ->modify("midnight") не устанавливает время в начало суток. В документации такого модификатора нету. Для того, чтобы установить начало дня можно использовать ->startOfDay().

    То есть ваш код принимает такой вид:
    $initial = Carbon::createFromTimestamp(1485943200);
    $moscow_midnight = $initial->copy()->timezone('Europe/Moscow')->startOfDay()->getTimestamp();
    $samara_midnight = $initial->copy()->timezone('Europe/Samara')->startOfDay()->getTimestamp();


    Еще нужно понимать, что в том коде что у вас под "этим днем" подразумевается день в часовом поясе UTC. Если вас интересует день в другом часовом поясе, нужно делать по-другому.

    Я бы советовал заменить createFromTimestamp на createFromTimestampUtc - так поведение скрипта будет более прозрачно/очевидно. Хотя, фактически оно не изменится, но если, допустим, кто-то будет дебажить его может получиться "странная" ситуация. Если запустить код в phpio.net/tools/carbon

    echo '<br />';require 'Carbon/Carbon.php';
    use Carbon\Carbon;
    
    $initial = Carbon::createFromTimestamp(0);
    echo "{$initial} {$initial->tzName}<br />";
    $samara = $initial->copy()->timezone('Europe/Samara')->startOfDay();
    echo "{$samara} {$samara->tzName}<br />";
    
    $initial = Carbon::createFromTimestampUtc(0);
    echo "{$initial} {$initial->tzName}<br />";
    $samara = $initial->copy()->timezone('Europe/Samara')->startOfDay();
    echo "{$samara} {$samara->tzName}<br />";


    его вывод будет таким:


    1969-12-31 18:00:00 US/Central
    1970-01-01 00:00:00 Europe/Samara
    1970-01-01 00:00:00 +00:00
    1970-01-01 00:00:00 Europe/Samara


    И если бы выводилось только время, без часового пояса, оно могло бы смутить в первом случае, так как даты не совпадают.
    Ответ написан