How can I set the User's Timezone to be the timezone of their OS/Browser

Mathieu8
Kilo Guru

Hi,

We want to set the Timezone on the user table to the location the user is currently at. If they are on a business trip, and their computer is displaying the time in that location, we want the experience to be the same within ServiceNow.

My best thought is to include the moment-timezone library, guess their timezone, map it to the Timezones in ServiceNow, and then update the sys_user table. The Ideally this would be executed on login.

 

1. How do I call the moment-timezone library from a UI Script?

2. How do I execute a UI Script only after login?

3. Is there a different method to do this?

 

Thanks!

1 ACCEPTED SOLUTION

Mathieu8
Kilo Guru

I've figured out how to reference the moment-timezone.js UI Script. I had to add moment.js UI Script separately since I don't believe it exists. Here is the code I've written to identify their timezone.

//TODO: Probably should provide a way for the user to block this
//TODO: Should we add a confirmation if we're gonna change their Timezone?
function sameTimezone(tz1, tz2){
  var zone1 = moment.tz.zone(tz1),
      zone2 = moment.tz.zone(tz2),
      abbrs1 = zone1 ? zone1.abbrs : null,
      abbrs2 = zone2 ? zone2.abbrs : null;

  return tz1 === tz2 //the same string
    ||
  (abbrs1 && abbrs1.indexOf(tz2) !== -1) //tz2 is an abbr and in tz1's abbrs
    ||
  (abbrs2 && abbrs2.indexOf(tz1) !== -1) //tz1 is an abbr and in tz2's abbrs
    ||
  (abbrs1 && abbrs2 && abbrs1 === abbrs2); //tz1 and tz2 are not null and both are the same abbrs
}

addLoadEvent( function() {
	if(window.frameElement && window.location.pathname === '/login_redirect.do'){		
		ScriptLoader.getScripts(['moment.js.jsdbx','moment-timezone.js.jsdbx'], function(){
			var timezones = [];
			var guess = moment.tz.guess(true); //Guess the user's timezone
			var snGuess;

			//Get all the timezones from the form
			var formTimezones = new GlideRecord('sys_choice');
			formTimezones.addQuery('name', 'sys_user');
			formTimezones.addQuery('element', 'time_zone');
			formTimezones.addQuery('inactive', 'false');
			formTimezones.query();

			while(formTimezones.next()){
				timezones.push(formTimezones.value);
			}

			//If the guess is a timezone choice, use it.
			if(timezones.indexOf(guess) !== -1){
				snGuess = timezones[timezones.indexOf(guess)];
			}else{
				//Loop through the timezones and find one that is the same as our guess
				for(var i=0; i<timezones.length; i++){
					if(sameTimezone(guess, timezones[i])){
						snGuess = timezones[i];
					}
				}
			}

			//If we've made a guess, lets grab the user's current timezone
			if(snGuess){
				var user = new GlideRecord('sys_user');
				user.addQuery('sys_id', g_user.userID);
				user.query();
				if(user.next()){
					//If their timezone currently and our guess are different, update it
					//Note: If our guess is America/Los_Angeles, and their timezone is US/Pacific,
					//      it will not be changed since they are the same timezone.
					if(!sameTimezone(snGuess, user.time_zone)){
						user.time_zone = snGuess;
						user.update();
					}
				}
			}

		});
	}
});

View solution in original post

7 REPLIES 7

This is great, thanks Mathieu. Appreciate you sharing the code!

Hey Mathieu,

 

I am working on similar implementation, so you have used the already existing UI Script or have created new one ?

 

THanks in advance!

Hi Chaisai,

 

I created a new UI Script with the script above.

 

API Name: Anything you want

Application: Global

UI Type: Desktop

Active: True

Global: True

Description: Anything you want

Script: <copied from above>

 

Also, be sure to add an updated version of moment.js moment-timezone.js to your UI Scripts for the ScriptLoader.getScripts to grab.