Yakın çeyrek saat aşağı yuvarlak dakika

8 Cevap php

Ben PHP yakın çeyrek saat sürelerini yuvarlamak gerekir. Kez datetime sütunundaki bir MySQL veritabanı çekti ve 2010-03-18 10:50:00 gibi biçimlendirilir ediliyor.

Örnek:

  • 10:50 10:45 olması gerekir
  • 01:12 01:00 olması gerekir
  • 03:28 03:15 olması gerekir
  • vb

I floor() dahil ama bu konuda gitmek nasıl emin değil varsayarak yaşıyorum.

Teşekkürler

8 Cevap

Sizin tam fonksiyon böyle bir şey olurdu ...

function roundToQuarterHour($timestring) {
    $minutes = date('i', strtotime($timestring));
    return $minutes - ($minutes % 15);
}
$seconds = time();
$rounded_seconds = round($seconds / (15 * 60)) * (15 * 60);

echo "Original: " . date('H:i', $seconds) . "\n";
echo "Rounded: " . date('H:i', $rounded_seconds) . "\n";

Bu örnek, şimdiki zaman alır ve nearest çeyrek ve baskılar özgün ve yuvarlak zaman hem onu ​​yuvarlar.

PS: Eğer down ile round() olarak değiştirin onu yuvarlamak istiyorsanız floor().

Son zamanlarda ben bir sorunu TDD/unit testing yolunu mücadele seviyorum. Ben son zamanlarda artık çok PHP programlama değilim, ama bu ben ile geldi budur. Dürüst olmak gerekirse ben aslında burada kod örnekleri baktı, ve ben zaten doğru olduğunu düşündüm birini aldı. Sonraki Ben Yukarıda verilen testler kullanılarak birim testleri ile bu doğrulamak istiyordu.

class TimeTest

require_once 'PHPUnit/Framework.php';
require_once 'Time.php';

class TimeTest extends PHPUnit_Framework_TestCase 
{
    protected $time;

    protected function setUp() {
        $this->time = new Time(10, 50);
    }

    public function testConstructingTime() {
        $this->assertEquals("10:50", $this->time->getTime());
        $this->assertEquals("10", $this->time->getHours());
        $this->assertEquals("50", $this->time->getMinutes());        
    }

    public function testCreatingTimeFromString() {
        $myTime = Time::create("10:50");
        $this->assertEquals("10", $myTime->getHours());
        $this->assertEquals("50", $myTime->getMinutes());
    }

    public function testComparingTimes() {
        $timeEquals     = new Time(10, 50);
        $this->assertTrue($this->time->equals($timeEquals));
        $timeNotEquals  = new Time(10, 44);
        $this->assertFalse($this->time->equals($timeNotEquals));
    }


    public function testRoundingTimes()
    {
        // Round test time.
        $roundedTime = $this->time->round();
        $this->assertEquals("10", $roundedTime->getHours());
        $this->assertEquals("45", $roundedTime->getMinutes());

        // Test some more times.
        $timesToTest = array(
            array(new Time(1,00), new Time(1,12)),
            array(new Time(3,15), new Time(3,28)),
            array(new Time(1,00), new Time(1,12)),
        );

        foreach($timesToTest as $timeToTest) {
            $this->assertTrue($timeToTest[0]->equals($timeToTest[0]->round()));
        }        
    }
}

class Time

<?php

class Time
{
    private $hours;
    private $minutes;

    public static function create($timestr) {
        $hours      = date('g', strtotime($timestr));
        $minutes    = date('i', strtotime($timestr));
        return new Time($hours, $minutes);
    }

    public function __construct($hours, $minutes) {
        $this->hours    = $hours;
        $this->minutes  = $minutes;
    }

    public function equals(Time $time) {
        return  $this->hours == $time->getHours() &&
                 $this->minutes == $time->getMinutes();
    }

    public function round() {
        $roundedMinutes = $this->minutes - ($this->minutes % 15);
        return new Time($this->hours, $roundedMinutes);
    }

    public function getTime() {
        return $this->hours . ":" . $this->minutes;
    }

    public function getHours() {
        return $this->hours;
    }

    public function getMinutes() {
        return $this->minutes;
    }
}

Running Test

alfred@alfred-laptop:~/htdocs/time$ phpunit TimeTest.php 
PHPUnit 3.3.17 by Sebastian Bergmann.

....

Time: 0 seconds

OK (4 tests, 12 assertions)

Benim sistem için benim sunucuda her 5 dakika çalışacak planlanan işleri eklemek istedim, ve ben aynı işi, sonra 15, 30, 60, 120, 240 dakika, 1 gün sonraki 5 dakikalık blokta çalıştırmak istiyorum ve 2 gün sonra, böylece ne bu işlevi hesaplar

function calculateJobTimes() {
    $now = time();
    IF($now %300) {
        $lastTime = $now - ($now % 300);
    }
    ELSE {
        $lastTime = $now;
    }
    $next[] = $lastTime + 300;
    $next[] = $lastTime + 900;
    $next[] = $lastTime + 1800;
    $next[] = $lastTime + 3600;
    $next[] = $lastTime + 7200;
    $next[] = $lastTime + 14400;
    $next[] = $lastTime + 86400;
    $next[] = $lastTime + 172800;
    return $next;
}

echo "The time now is ".date("Y-m-d H:i:s")."<br />
Jobs will be scheduled to run at the following times:<br /><br />
<ul>";
foreach(calculateJobTimes() as $jTime) {
    echo "<li>".date("Y-m-d H:i:s", $jTime).'</li>';
}
echo '</ul>';

Ben güne aşağı yuvarlamak için bir yol gerekli, ve bunun ötesinde her şeyi kesti:

$explodedDate = explode("T", gmdate("c",strtotime("now")));
$expireNowDate =  date_create($explodedDate[0]);

O, bana vererek, "T" patlayabilir kullanın ": strtotime bana gmdate ISO biçiminde (" 00:00 +00:00 2012-06-05T04 "gibi bir şey) dönüştüren" şimdi "için bir zaman damgası verir sonra bir tarih nesnesi almak için date_create geçirilir $ explodedDate, sıfırıncı endeksinde 2012-06-05 ".

Emin tüm gerekli, ancak geçiyor ve saniye, dakika, saat vb çıkararak çok daha az iş gibi görünüyor değilse

Kodunun altına yakın çeyrek saatlik kullanımını yuvarlamak için

<?php
$time = strtotime("01:08");
echo $time.'<br />';
$round = 15*60;
$rounded = round($time / $round) * $round;
echo date("H:i", $rounded);
?>

01:08 01:15 olmak

Ben saniye veya dakika zaman damgalarını yuvarlamak için hile yapan bir fonksiyon yazdım.

Ben en çok ölçülebilir bir yol olmayabilir, ama ben PHP bir kaç basit döngüler hakkında dikkat doens't düşünüyorum.

Senin durumunda, sadece bu gibi MySQL datetime geçmek:

<?php echo date('d/m/Y - H:i:s', roundTime(strtotime($MysqlDateTime), 'i', 15)); ?>

İade: Closests (hem aşağı hem yukarı görünüyor!) Değer yuvarlanır

Fonksiyonu:

<?php
function roundTime($time, $entity = 'i', $value = 15){

    // prevent big loops
    if(strpos('is', $entity) === false){
        return $time;
    }

    // up down counters
    $loopsUp = $loopsDown = 0;

    // loop up
    $loop = $time;
    while(date($entity, $loop) % $value != 0){
        $loopsUp++;
        $loop++;
    }
    $return = $loop;    


    // loop down
    $loop = $time;
    while(date($entity, $loop) % $value != 0){
        $loopsDown++;
        $loop--;
        if($loopsDown > $loopsUp){
            $loop = $return;
            break;  
        }
    }
    $return = $loop;

    // round seconds down
    if($entity == 'i' && date('s', $return) != 0){
        while(intval(date('s', $return)) != 0){
            $return--;
        }
    }
    return $return;
}
?>

Eğer saniye veya aşağı yukarı yuvarlak ve ya aşağı yukarı ROUD istediğiniz saniye veya dakika miktarına göre 15 yerine isterseniz basit bir 's' ile $ varlık değiştirin.

İşte anda kullanarak bir fonksiyon:

/**
 * Rounds a timestamp
 *
 * @param int $input current timestamp
 * @param int $round_to_minutes rounds to this minute
 * @param string $type auto, ceil, floor
 * @return int rounded timestamp
 */
static function roundToClosestMinute($input = 0, $round_to_minutes = 5, $type = 'auto')
{
    $now = !$input ? time() : (int)$input;

    $seconds = $round_to_minutes * 60;
    $floored = $seconds * floor($now / $seconds);
    $ceiled = $seconds * ceil($now / $seconds);

    switch ($type) {
        default:
            $rounded = ($now - $floored < $ceiled - $now) ? $floored : $ceiled;
            break;

        case 'ceil':
            $rounded = $ceiled;
            break;

        case 'floor':
            $rounded = $floored;
            break;
    }

    return $rounded ? $rounded : $input;
}

Birine yardımcı olur umarım :)