Search code examples
javascriptpythondjangotimezonegettime

Django python + javascript countdown – different times in Python and Javascript?


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!


Solution

  • 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.