Это НЕ домашнее задание, и мне нужно время, чтобы объяснить.
Каждый раз, когда мне нужно найти, сколько процентов Икс Y Значение представляет, я использую эту формулу:
D = BC / A
Это контрактная версия того, что мы узнали в школе:
A --- B
C --- C
Будучи:
Например:
В корзине с 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-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);
перевести в минуты?
$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);
Я не очень знаком с PHP или объектом PHP DateTime, но использую вашу формулу сверху:
D = BC / A
$ A = $ dt1 :: getTimeStamp ();
$ B = 100;
$ C = $ dt2 :: getTimeStamp ();
$ D = ($ B * $ C) / $ A;