/** * Set the current time of the running assessment test session. * * @param \DateTime $time */ public function setTime(DateTime $time) { // Force $time to be UTC. $time = Time::toUtc($time); if ($this->hasTimeReference() === true) { if ($this->getState() === AssessmentTestSessionState::INTERACTING) { $diffSeconds = abs(Time::timeDiffSeconds($this->getTimeReference(), $time)); $diffDuration = new QtiDuration("PT{$diffSeconds}S"); // Update the duration store. $routeItem = $this->getCurrentRouteItem(); $durationStore = $this->getDurationStore(); $assessmentTestDurationId = $routeItem->getAssessmentTest()->getIdentifier(); $testPartDurationId = $routeItem->getTestPart()->getIdentifier(); $assessmentSectionDurationIds = $routeItem->getAssessmentSections()->getKeys(); foreach (array_merge(array($assessmentTestDurationId), array($testPartDurationId), $assessmentSectionDurationIds) as $id) { $durationStore[$id]->add($diffDuration); } // Adjust durations if they exceed the time limits in force. $timeConstraints = $this->getTimeConstraints(); foreach ($timeConstraints as $timeConstraint) { if ($timeConstraint->maxTimeInForce() === true) { $identifier = $timeConstraint->getSource()->getIdentifier(); $maxTime = $timeConstraint->getSource()->getTimeLimits()->getMaxTime(); if (($duration = $durationStore[$identifier]) !== null && $duration->longerThanOrEquals($maxTime)) { $durationStore[$identifier] = clone $maxTime; } } } // Let's update item sessions time. foreach ($this->getAssessmentItemSessionStore()->getAllAssessmentItemSessions() as $itemSession) { $itemSession->setTime($time); } // Let's now check if the test itself, the current test part // or current sections are timed out. If it's the case, we will // have to close some item sessions. foreach ($timeConstraints as $timeConstraint) { if ($timeConstraint->maxTimeInforce() && $timeConstraint->getMaximumRemainingTime()->getSeconds(true) === 0) { $routeItemsToClose = new RouteItemCollection(); $route = $this->getRoute(); $source = $timeConstraint->getSource(); if ($source instanceof AssessmentTest) { $this->endTestSession(); break; } elseif ($source instanceof TestPart) { $routeItemsToClose = $route->getRouteItemsByTestPart($source); } elseif ($source instanceof AssessmentSection) { $routeItemsToClose = $route->getRouteItemsByAssessmentSection($source); } if (count($routeItemsToClose) > 0) { foreach ($routeItemsToClose as $routeItem) { $itemRef = $routeItem->getAssessmentItemRef(); $occurence = $routeItem->getOccurence(); $session = $this->getItemSession($itemRef, $occurence)->endItemSession(); } break; } } } } } // Update reference time with $time. $this->setTimeReference($time); }
/** * Set the current time of the running assessment item session. * * If the session is in INTERACTING mode, the difference between the last time reference provided * with the previous call on the setTime() method and $time will be computed. This * time difference will be added to the current value of the built-in outcome variable * 'duration'. * * If the value of the built-in outcome variable 'duration' exceeds the maximum time limit * in force, the session will be closed by performing an internal call to the endItemSession() * method. * * @param \DateTime $time The current time that will be taken into account for all next interactions with the object. * @see \qtism\runtime\tests\AssessmentItemSession::endItemSession() The endItemSession() method. */ public function setTime(DateTime $time) { // Force time to be UTC. $time = Time::toUtc($time); if ($this->hasTimeReference() === true) { if ($this->getState() === AssessmentItemSessionState::INTERACTING) { // The session state is INTERACTING. Thus, we need to update the built-in // duration variable. $diffSeconds = Time::timeDiffSeconds($this->getTimeReference(), $time); $diffDuration = new QtiDuration("PT{$diffSeconds}S"); $this['duration']->add($diffDuration); } if ($this->isMaxTimeReached() === true) { // -- Maximum time is reached, close the session. // Limit duration to max time if needed. $tl = $this->getTimeLimits(); if (($maxTime = $tl->getMaxTime()) !== null && $maxTime->shorterThan($this['duration']) === true) { $newDuration = clone $maxTime; $this['duration'] = $newDuration; } $this->endItemSession(); } } // Update reference time with $time. $this->setTimeReference($time); }
public function testBasicToUtc() { $originalTime = DateTime::createFromFormat('Y-m-d G:i:s', '2014-07-15 16:56:20', new DateTimeZone('Europe/Luxembourg')); $utcTime = TimeUtils::toUtc($originalTime); $this->assertEquals('2014-07-15 14:56:20', $utcTime->format('Y-m-d H:i:s')); }