I realize this is only half a Django issue, but I feel like I can get some advice here.
Here’s the background: I have an LMS app which allows teachers to create exams which can optionally have a time limit. When undertaking an exam which has a time limit, students are shown a timer which informs them of how much remaining time they have.
In order to implement this, I have a field called begin_timestamp
on the model that represents the user participation into the exam, which of course is a DateTime field which gets populated with the current date and time upon participation instance creation. Moreover, the exam model has a field named time_limit_seconds
, which holds the integer number of seconds of the time limit (I chose to use seconds in order to be able to represent fraction-of-a-minute times with integer values).
The value for begin_timestamp
is serialized by DRF and sent in this format: "2023-02-08 09:32:39"
.
This function on the frontend determines how many seconds are left for the current participation—it is called when the student beings the exam (or reloads the exam page) and serves as a starting value for the countdown timer:
export const getParticipationRemainingTime = (
participation: ExamParticipation,
exam: Exam,
): number | null => {
if (exam.time_limit_seconds === null) {
return null;
}
const endDate = new Date(participation.begin_timestamp);
endDate.setSeconds(endDate.getSeconds() + exam.time_limit_seconds);
return Math.max(Math.floor((endDate.getTime() - new Date().getTime()) / 1000), 0);
};
I’ll quickly note that this is only “cosmetic”, in order to show the student a timer during the exam: the actual checking is done on the backend.
So, here’s the issue: yesterday a foreign student was taking a university exam on my LMS platform. Apparently, she had a different timezone than that of the server: one hour forward. The exam had a time limit of less than an hour.
What happened is that, as soon as she started the exam, the timer showed her 0 seconds remaining.
What I realized, after investigating a bit, is that the culprit was most likely her timezone.
In particular, in the function above, while all calculations are done from the datetime sent by the backend, the new Date()
instruction relies on the device datetime; therefore, if the two timezones don’t match, we have a problem.
I believe I could solve my issue by using a more “absolute” calculation, i.e. since all I want to measure is elapsed seconds since a reference starting point, I should be able to make a determination as to how much time the user has left solely based on the timestamps, by subtracting seconds.
How would you achieve this?
I apologize once again for the likely not-so-relevant question, but I have little knowledge of all things dates, so I’m trying to make sense of all the different formats etc. I feel like just sending the number of seconds since Jan 1st 1970 could be the right way to perform this computation, but I’m definitely open to advice.