Hi, I am experiencing inconsistencies with time calculations in my Laravel online examination platform when accessing it from different machines. Currently it is access via locacl host. php artisan serve --host 192.168.0.101 --port 80. the time left will either be higher than the speculated time for the quiz or less than while in a few other laptops it is correct.
I keep track of when the users starts the exams in my db
public function up(): void
{
Schema::create('exam_histories', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('assessment_id')->constrained()->onDelete('cascade');
$table->foreignId('quiz_id')->constrained()->onDelete('cascade');
$table->date('exam_date');
$table->timestamp('start_time');
$table->timestamp('ends_at')->nullable();
$table->timestamps();
});
}
Before the exams starts I return the page along with the time start stored in the database
return Inertia::render('User/TakeAssessment/Live-Exam', [
'quiz' => new QuizResource($quiz),
'questions' => $quiz->questions->shuffle(),
'start_time' => $session->start_time,
'user_responses'=> $user_responses
]);
then on the vue page the start time is received and passed to the timer component
<script>
export default {
layout: Layout,
components: {Modal, Timer, Question, Questions},
props: ['questions','quiz','start_time','user_responses'],
The Timer Component
<template>
<div>
<span v-if="!hasEnded">{{ timeLeft }}</span>
<span v-else>Time's Up!</span>
</div>
</template>
<script>
export default {
props: {
duration: {
type: Number,
required: true,
},
startTime: {
type: Date,
required: true,
},
},
data() {
return {
intervalId: null,
currentTime: new Date(),
};
},
computed: {
timeLeft() {
const targetTime = new Date(this.startTime);
targetTime.setMinutes(targetTime.getMinutes() + this.duration);
const difference = targetTime.getTime() - this.currentTime.getTime();
if (difference <= 0) {
return null;
}
const seconds = Math.floor((difference / 1000) % 60);
const minutes = Math.floor((difference / (1000 * 60)) % 60);
const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
},
hasEnded() {
return this.timeLeft === null;
},
},
mounted() {
this.intervalId = setInterval(this.updateTime, 1000);
},
beforeDestroy() {
clearInterval(this.intervalId);
},
methods: {
updateTime() {
this.currentTime = new Date();
if (this.hasEnded) {
this.$emit('timeUp'); // Emit event when time is up
}
this.$forceUpdate();
},
},
};
</script>
<style scoped>
/* Add your styling here */
</style>