How can I capture survey respondents timezone as embedded data? | XM Community
Solved

How can I capture survey respondents timezone as embedded data?


Badge +6

Hello everyone!
I've inherited a survey that has some custom JS meant to capture respondent timezone, but it works inconsistently and doesn't capture it for everyone. I know next to nothing about JS, and was wondering if anyone can see where the issue might lie:

// Capturing respondent's time zone

Qualtrics.SurveyEngine.addOnReady(function()
{
  waitForElement();

});

Qualtrics.SurveyEngine.addOnUnload(function()
{

});

function waitForElement(){
    if(typeof moment !== "undefined"){
      setEmbeddedTimezone("timezone", "timezone_abbrev");
    }
    else{
      setTimeout(waitForElement, 250);
    }
}

function setEmbeddedTimezone(tzEmbed, abrEmbed){
  try{
    if ((tzEmbed === null || tzEmbed === undefined) || (abrEmbed === null || abrEmbed === undefined)){
      console.log("No Embedded Data fields provided.")
      return;
    }

    var timezone = moment.tz.guess();
     
    if (timezone === null || timezone === undefined){
      console.log("Unable to retrieve timezone");
      return;
    }

    Qualtrics.SurveyEngine.setEmbeddedData(tzEmbed, timezone);
     
    var date = new Date();
    var timestamp = date.getTime();
    var abbr = moment.tz.zone(timezone).abbr(timestamp);

    Qualtrics.SurveyEngine.setEmbeddedData(abrEmbed, abbr);
  }
  catch(e){
    console.log(e);
  }
}

icon

Best answer by bgooldfed 18 May 2022, 03:37

View original

7 replies

Userlevel 5
Badge +25

Hi tscott,
Do you get the same result if you use Intl.DateTimeFormat().resolvedOptions().timeZone? A quick look at the documentation for Moment suggests that guess() first uses this command, and if it fails it attempts to guess by calculating the difference in offset. resolveOptions().timeZone works in over 90% of browsers, so unless you're targeting old browsers it should work fine.
If that still fails, try using moment.tz.guess(true) to clear its cache. Again, from the documentation:
"By default Moment Timezone caches the detected timezone. This means that subsequent calls to 

moment.tz.guess()
 will always return the same value.
You can call 
moment.tz.guess()
 with an optional boolean argument "ignoreCache". If set to true, the cache will be ignored and overwritten with the new value."
Good luck!

Badge +6

Thanks for your response bgooldfed!
Just to clarify, I would just need to swap out the single var timezone piece with either of those values, correct?

So either:
var timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
or
var timezone = moment.tz.guess(true);
Right?

Userlevel 5
Badge +25

That is correct :)

Badge +6

Thanks so much bgooldfed, the first option worked!

As a separate but related question, do you know of any other options to get the abbreviation to work? It seems like that condition is working to mixed results similar to how the timezone field was prior to the change:
Screen Shot 2022-05-18 at 9.48.56 AM.pngLooks like this section should be doing that abbreviation, but I'm not sure where the issue is after looking at the documentation you sent.
    var date = new Date();
    var timestamp = date.getTime();
    var abbr = moment.tz.zone(timezone).abbr(timestamp);
At the end of the day it's not a huge deal since I can always just use branch logic in the survey flow to take care of it, but if JS can do it for me I won't complain 😁

Userlevel 5
Badge +25

Glad you got it working!
That is very odd regarding the abbreviations, it should work fine how you have it... Are you able to confirm that the timestamp variable is working properly?
You could also try:
var abbr = moment.tz(timezone).format('z')
However that won't capture daylight savings time (because it only checks the general timezone, not the actual time of year).

Badge +6

bgooldfed I'm almost wondering if maybe Moment wasn't properly loaded into the survey since in testing, moment.tz.guess(true) didn't work. Taking a look at the JS in the very first question prior to the one that contains the code block in my first message, I can see the following:
{
/*Place your JavaScript here to run when the page loads*/

// Loading scripts to capture respondent's time zone
var loadedMoment = loadScript("https://momentjs.com/downloads/moment.min.js");
var loadedTimezone = loadScript("https://momentjs.com/downloads/moment-timezone-with-data-1970-2030.min.js");
   
  if (loadedMoment && loadedTimezone){
    waitForElement();
  }
Looking at the documentation it looks like this should be used instead? Just not sure how I would need to change the above to accommodate for that.

As always, thank you so much for your help! Really appreciate you taking the time to help me learn!

Userlevel 5
Badge +25

Try popping those script tags in the docs into the header of your survey. See point #5 on this Qualtrics article for some more info and a link to instructions.
That should let you call moment from anywhere in your survey.

Leave a Reply