EDIT #2
Again, I spend some time with the code and some more research:
In my views.py I do the following
timestamp = datetime.combine(inst.date, inst.time).strftime('%s')
timestamp
get passed through the template to javascript.
But the unexplainable (for me) happens in the views.py
Output views.py
Timestamp: 2022-02-03 20:10:00
Timestamp.strftime('%s'): 1643919000
Output javscript
Date Thu Feb 03 2022 21:10:00 GMT+0100 (Central European Standard Time) 1643919000000
The (milli-)seconds outputs are basically the same but the datetime.datetime object
in Python and the Date
object in Javascript is different.
What magic is at play here?
EDIT
After some re-tuning (thanks to Kyvex in the comments), I got the gap down to one hour. Which is now somehow explainable:
This is the .js code now:
var countDownDate = JSON.parse(document.getElementById('timestamp').textContent); //new Date("Feb 2, 2022 22:59:00 GMT+0000").getTime();
var x = setInterval(function () {
var now = new Date().getTime();
console.log(countDownDate);
const GMT = 3600000;
console.log(now);
var difference = countDownDate * 1000 - now - GMT;
var days = Math.floor(difference / (1000 * 60 * 60 * 24));
var hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((difference % (1000 * 60)) / 1000);
document.getElementById("clock").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (difference < 0) {
clearInterval(x);
document.getElementById("clock").innerHTML = "<h1>EXPIRED!</h1>";
}
}, 1000);
I logged both countDownDate
and now
. It seems like they use different offsets. countDownDate
, coming from python, seems to have an offset of GMT+0000, whereas now
returns a GMT+0100. I now hard-coded this difference by subtracting const GMT = 3600000
. But this cannot be the solution to the problem.
How can I get them in sync?
I am relatively new and just a hobbyist programmer. At the moment I try to work on a small Django project where I want to set a date and time in the future via a form and after the user clicks "Submit", the page shows a countdown from now until the set date and time.
After experimenting a bit with the datetime module, I find myself with an awkward problem. I have two fields in the forms: 1. date, and 2. time
With timestamp = datetime.datetime.combine(date, time).strftime('%s')
I combine those two information and get a seconds output. I then, pass timestamp
to my .js file with {{ timestamp|json_script:'timestamp'}}
.
Here is my .HTML code:
<body>
{% load static %}
<html>
<form method="post" enctype="multipart/form-data">
{% csrf_token %} {{ form.as_p }}
<button type="submit">Submit</button>
</form>
{% if inst %}
<center><h3>Success</h3>
<div id="clock"></div></center>
{{ timestamp | json_script:'timestamp'}}
<script src="{% static 'js/timer.js' %}"></script>
{% endif %}
</html>
</body>
If I now set setTime
only 2 minutes in the future, my countdown shows 4 hours, and the difference
is 3 hours.
I get that there are timezone and DST differences at play but from where I am nothing would add up to 3 or 4 hours.
Excuse me if this is all too unprofessional and just a lay description of my problem. I would appreciate the community's help since I am trying to get better and understand all those underlying processes here.
Thanks a lot!
I just solved it!!
Here is my .js code
var countDownDate = JSON.parse(document.getElementById('timestamp').textContent);
var newDate = new Date(countDownDate * 1000);
// Get NOW
var now = new Date();
// Get Timezone offset from imported date
var tzDifference = newDate.getTimezoneOffset();
// calculate the new offset time
var offsetNewTime = new Date(newDate.getTime() + tzDifference * 60 * 1000)
var x = setInterval(function () {
var now = new Date();
// console.log(now.getTime());
var difference = offsetNewTime - now;
var days = Math.floor(difference / (1000 * 60 * 60 * 24));
var hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((difference % (1000 * 60)) / 1000);
document.getElementById("clock").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (difference < 0) {
clearInterval(x);
document.getElementById("clock").innerHTML = "<h1>EXPIRED!</h1>";
}
}, 1000);
With the help from this post: add or subtract timezone difference to javascript Date
Somehow I got two different time offsets from python and javascript. So I used getTimezoneOffset();
to account for that and add this offset to the imported datetime.
This just works now and I hope it does independently of the timezone one finds themselves in.
If you have any comments on that please feel free to add them, of course.