Процент между двумя объектами DateTime

Это НЕ домашнее задание, и мне нужно время, чтобы объяснить.


Каждый раз, когда мне нужно найти, сколько процентов Икс Y Значение представляет, я использую эту формулу:

D = BC / A

Это контрактная версия того, что мы узнали в школе:

A --- B
C --- C

Будучи:

  • значение, которое я знаю и представляет 100% от суммы
  • В сколько всего представляет (всегда 100)
  • С значение, которое я знаю и представляю ИКС% от суммы
  • D ИКС% я хочу знать

Например:

В корзине с 10 яблоками 6 из них хорошо поесть. Сколько яблок, в процентах, должно пойти в мусорное ведро?

D = BC / A
D = ( 100 * 6 ) / 10
D = 60%

В этом примере D представляет количество хороших яблок (6), поэтому остальные 40% (4) должны идти в корзину. : D

Все хорошо? Позвольте мне продолжить.

Но как насчет времени? Рассмотрим этот сценарий:

У бегового теста (как марафон) есть ограничение по времени 10 минут. Если бегун заканчивает тест через 5 минут, насколько быстро он был относительно общего времени?

Ответ однозначен 50% но при использовании схемы выше в коде ниже, я не получаю этот результат.

Первым делом я создал оба объекта DateTime и отформатировал их до секунд, используя этот ответ Я нашел здесь:

$total      = "00:10:00";
$running    = "00:05:00";

$dt1 = DateTime::createFromFormat( 'H:i:s', $total );
$dt1f = $dt1 -> format( 'U' ); // 1415067000

$dt2 = DateTime::createFromFormat( 'H:i:s', $running );
$dt2f = $dt2 -> format( 'U' ); // 1415066700

И тогда я заполнил переменные в (контрактной) формуле:

$x = ( ( 100 * $dtf2 ) / $dtf1 ); // 99.99997879959

Сначала я подумал, что это может быть проблема с форматированием DateTime, поэтому я фальсифицировал день, месяц и год, выбрасывая их до 1 января 1970 года и, таким образом, получая меньшие значения:

$total      = "1970-01-01 00:10:00";
$running    = "1970-01-01 00:05:00";

$dt1 = DateTime::createFromFormat( 'Y-m-d H:i:s', $total );
$dt1f = $dt1 -> format( 'U' ); // 11400

$dt2 = DateTime::createFromFormat( 'Y-m-d H:i:s', $running );
$dt2f = $dt2 -> format( 'U' ); // 11100

Но вместо того, чтобы получать меньшее и правильное значение, теперь $ х привело к +97,368421052632 o.o

Я проверил полученный метки времени с date () на всякий случай, чтобы убедиться, что они представляли, соответственно 10 и 5 минут, и они в порядке.

Хотя математика верна (я бегал в калькуляторе), логика не вычисляет, как я ожидал.

Есть какие-нибудь подсказки?

-1

Решение

Проблема со вторым (код, скорректированный на эпоху) состоит в том, что ваше нулевое время настроено на часовой пояс. Если бы вы проверить время для 1-1-1970 00:00:00 это не вернет метку времени 0 но независимо от смещения часового пояса в секундах. Вы можете увидеть это, посмотрев на свои временные метки. 10 минут — это 600 секунд (10 * 60), а не 11400 секунд (что будет 3 часа 10 минут, поэтому я предполагаю, что для сервера установлен часовой пояс +3). Вам нужно получить 00:00:00 оцените и вычтите это из обоих ваших чисел сначала, чтобы получить истекшее и продолжительность времени.

И для полной даты у вас есть похожая проблема. Вы предполагаете, что 0 сегодня в 00:00:00 но на самом деле это эпоха Unix (+/- часовой пояс). Итак, вы смотрите на 300 секунд между двумя числами по сравнению с 44 годами секунд. Что равняется примерно 99,999 …% пути.

Пример (нажмите, чтобы увидеть результат):

<?php
$start      = "00:00:00";
$total      = "00:10:00";
$running    = "00:05:00";

$dt0 = DateTime::createFromFormat( 'H:i:s', $start );
$dt0f = $dt0 -> format( 'U' );

$dt1 = DateTime::createFromFormat( 'H:i:s', $total );
$dt1f = $dt1 -> format( 'U' );

$dt2 = DateTime::createFromFormat( 'H:i:s', $running );
$dt2f = $dt2 -> format( 'U' );

//get the duration of time from start to end
$duration = $dt1f - $dt0f;
//get the elapsed amount of time from the start to running
$elapsed = $dt2f - $dt0f;

$pct = ((100 * $elapsed) / $duration);

//outputs: 50
var_dump($pct);

с учетом эпохи Unix (нажмите, чтобы увидеть результат) (тот же вывод):

<?php
$start      = "1970-01-01 00:00:00";
$total      = "1970-01-01 00:10:00";
$running    = "1970-01-01 00:05:00";

$dt0 = DateTime::createFromFormat( 'Y-m-d H:i:s', $start );
$dt0f = $dt0 -> format( 'U' );

$dt1 = DateTime::createFromFormat( 'Y-m-d H:i:s', $total );
$dt1f = $dt1 -> format( 'U' );

$dt2 = DateTime::createFromFormat( 'Y-m-d H:i:s', $running );
$dt2f = $dt2 -> format( 'U' );

//get the duration of time from start to end
$duration = $dt1f - $dt0f;
//get the elapsed amount of time from the start to running
$elapsed = $dt2f - $dt0f;

$pct = ((100 * $elapsed) / $duration);

var_dump($pct);
1

Другие решения

перевести в минуты?

$total      = "01:10:00";
$running    = "00:45:12";
function timesPercentDiff($ts1,$ts2)
{
list($hours1, $minutes1,$seconds1) = explode(':', $ts1);
list($hours2, $minutes2,$seconds2) = explode(':', $ts2);
$min1=$hours1 * 60 + $minutes1 + $seconds1/60;
$min2=$hours2 * 60 + $minutes2 + $seconds2/60;
return $min2/$min1*100;
}
echo  timesPercentDiff($total,$running);
1

Я не очень знаком с PHP или объектом PHP DateTime, но использую вашу формулу сверху:

D = BC / A

$ A = $ dt1 :: getTimeStamp ();

$ B = 100;

$ C = $ dt2 :: getTimeStamp ();

$ D = ($ B * $ C) / $ A;

0
По вопросам рекламы [email protected]