Changing list of time zone offset numbers to current times with JavaScript

Viewed 224

I am displaying a list of names and their time zone offset numbers in a table. The offset numbers are their time zone's offset from UTC. I need to change all of the offset numbers to show the current time in the person's time zone using JavaScript or jQuery.

What I would like to happen is the offset numbers would be replaced with the current date/time from the calcTime function... any idea what I'm doing wrong?

Here's my code:

<div class="name">John Doe</div><div class="timezone">-5</div>
<div class="name">Jane Doe</div><div class="timezone">3</div>
<div class="name">Jim Smith</div><div class="timezone">7</div>
<div class="name">Cathy Jones</div><div class="timezone">-3</div>

<script>
$(document).ready(function() {
    setTimeout(() => {
        function calcTime(offset) {
            // create Date object for current location
            d = new Date();
            // convert to msec
            // add local time zone offset
            // get UTC time in msec
            utc = d.getTime() + (d.getTimezoneOffset() * 60000);
            // create new Date object for different city
            // using supplied offset
            nd = new Date(utc + (3600000*offset));
            // return time as a string
            return "The local time is " + nd.toLocaleString();
        }

        $(".timezone").each(function(){
            h = $(this).find(".timezone").text();
            element.innerHTML = calcTime(h); 
        //alert(calcTime('-5'));
        });
    }, 1000);
});
</script>
3 Answers

I think this is what you are attempting to achieve (with significant changes).

Note the use of setInterval() rather than set time out and the structural changes to the HTML.

const utc = document.querySelector('.utc');
const collection = document.querySelectorAll('.timezone');
const outputs = document.querySelectorAll('.output');
const localeTZoffSet = new Date().getTimezoneOffset()/60 * 3600000;

setInterval(() => {
  utc.textContent = calcTime(0);
  collection.forEach((element, idx) => {
    outputs[idx].textContent = calcTime(element.textContent);
  });
});

function calcTime(offset) {
  return "The local time is " + new Date(Date.now() + localeTZoffSet + (3600000 * offset)).toLocaleTimeString();
}
<div>UTC: <span class="utc"></span></div>
<div class="name">John Doe - <span class="output"></span></div>
<div class="timezone">-5</div>
<div class="name">Jane Doe - <span class="output"></span></div>
<div class="timezone">3</div>
<div class="name">Jim Smith - <span class="output"></span></div>
<div class="timezone">7</div>
<div class="name">Cathy Jones - <span class="output"></span></div>
<div class="timezone">-3</div>

With @RandyCasburn 's help, I was able to get this to work:

$(document).ready(function() {
     const collection = document.querySelectorAll('.timezone');
     const outputs = document.querySelectorAll('.output');

     function calcTime(offset) {
         d = new Date();
         utc = d.getTime() + (d.getTimezoneOffset() * 60000);
         nd = new Date(utc + (3600000*offset));
         return nd.toLocaleString();
     }
     setInterval(() => {
        collection.forEach((element, idx) => {
           outputs[idx].textContent = calcTime(element.textContent);
           $(".timezone").hide();
        });
    });
});

<div class="name">John Doe - <span class="output"></span></div>
<div class="timezone">-5</div>
<div class="name">Jane Doe - <span class="output"></span></div>
<div class="timezone">3</div>
<div class="name">Jim Smith - <span class="output"></span></div>
<div class="timezone">7</div>
<div class="name">Cathy Jones - <span class="output"></span></div>
<div class="timezone">-3</div>

Thank you so much!

If I get the problem correctly.. .oO(lol)
You wish to display the realtime of each users based on their UTC offset.

I would have the user timezone in a data attribute to make sure to keep it handy.
(See changes made in your HTML below)
Then:

  • Create a local time object (where the page renders)
  • From the local time, you can get the UTC offset and the local hour.
  • Calculate the offset between the page viewer and the "other user".
    Meaning... As a page viewer I am in GMT-5 timezone, the first user (in your HTML) has a zero offset with me. Correct?
  • So starting from the local time and local GMT offset, add the "real time difference".
  • Sadly, the .setHours() method return milliseconds... So create a new date object with it.
  • Have it to a string and remove the part after "GMT-..." since this part is not accurate now.

Here is a demo with all the console.logs:

console.clear();

$(document).ready(function () {
  function calcTime(offset) {
    // That is a date object with the user's timezone
    let refDate = new Date();

    // So what is the user's timezone?
    let userTimezone = refDate.getTimezoneOffset() / 60;
    console.log("userTimezone", userTimezone);

    // What is the user's Hour?
    let localHour = refDate.getHours();
    console.log("localHour", localHour);

    // Make the calculation here
    let timeZoneDiff = offset + userTimezone;
    console.log("timeZoneDiff", timeZoneDiff);

    // Set the hour... But we still are in a "timezoned object"
    // and the .setHours returns milliseconds. ;(
    let hourRearanged = refDate.setHours(localHour + timeZoneDiff);
    console.log("hourRearanged", hourRearanged);

    // So re-generate a date object from that "arranged hour"
    let semiResult = new Date(hourRearanged).toString();
    console.log("semiResult were the part after GMT is wrong:", semiResult);

    console.log("---------------------------------------");
    
    // Rturn the part before "GMT"
    return semiResult.split("GMT")[0];
  }

  setInterval(() => {
    $(".name").each(function (index, element) {
      h = parseInt($(element).data("timezone"));
      $(element).next(".userTime").html(calcTime(h));
    });
  }, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="name" data-timezone="-5">John Doe (GMT-5)</div>
<div class="userTime">-5</div>
<div class="name" data-timezone="3">Jane Doe (GMT+3)</div>
<div class="userTime">3</div>
<div class="name" data-timezone="7">Jim Smith (GMT+7)</div>
<div class="userTime">7</div>
<div class="name" data-timezone="-3">Cathy Jones (GMT-3)</div>
<div class="userTime">-3</div>

Run in full page mode please...

Related