The CreatorCon Call for Content is officially open! Get started here.

Convert UTC to Time Zone (US/Eastern) from GlideRecord query output

keith_rokoske
Kilo Explorer

I'm relatively new to ServiceNow development and have encountered an issue that seems very simple but has thwarted me, thus far.   I've referenced:

Re: How to convert GMT date to ESTand other entries, but haven't been able to figure it out yet.

In a workflow script, there's a GlideRecord query (called, "sysapproval") that pulls some change request variables that are sent to an OnBase approval engine in an XML payload.   The fields, "current.sysapproval.start_date" and "current.sysapproval.end_date" are currently output in UTC.   Times need to be converted to system time (US/Eastern) or via the java time zone utilities: ("America/New_York").   Because these times aren't actually displayed in ServiceNow, they don't get automatically converted to the system time zone (US/Eastern).

I've tried to do this time zone conversion within the payload function via the GlideDateTime setTZ(tz) method: GlideDateTime - ServiceNow Wiki

var tz = Packages.java.util.TimeZone.getTimeZone("America/New_York");

var ps_dt = new GlideDateTime(current.sysapproval.start_date);

var plannedStartDt = ps_dt.setTZ(tz);

var pe_dt = new GlideDateTime(current.sysapproval.end_date);

var plannedEndDt = pe_dt.setTZ(tz);

However, when I do this, the resulting values in the XML get set to "undefined" and the approval engine chokes on the payload:

<Property><Name>Planned Start</Name><Value>undefined</Value></Property>

<Property><Name>Planned End</Name><Value>undefined</Value></Property>

I've tried to do this just about every alternative way I can think of but haven't had any success.   What am I missing?

Thanks,

Keith

16 REPLIES 16

stevejarman
Giga Guru

Hi - I'm new to ServiceNow and this is the first stumbling block that I've immediately run into. At this stage I'm just experimenting creating UI Actions to see what I can do. The first test that I've set for myself is:



Create a schedule for business hours 8am - 6pm.


Create a form where a u_startedwork date/time and u_endedwork date/time are entered.


Calculate what portion of the hours between those two date/times was within business hours.



Sounds simple... however I'm also running into these timezone issues and can't get this to work. Can anyone offer any further advice? Nothing in this thread seems to resolve the issue.



My current testing code looks like this. The display of the date/time values is correct, but the "hours" result is always 2 (instead of 1) due to those times being UTC (I assume) during the calculation.



gs.addInfoMessage(current.u_startedwork.getDisplayValue() + " --> " + current.u_endedwork.getDisplayValue());



var dc = new DurationCalculator();



var normalHoursSchedule = new GlideRecord('cmn_schedule');


normalHoursSchedule.addQuery('name', "8-6 weekdays");


normalHoursSchedule.query();



dc.setSchedule(normalHoursSchedule.getUniqueValue());



var dur = dc.calcScheduleDuration(current.u_startedwork, current.u_endedwork);


gs.addInfoMessage("Worked for " + dur/3600 + " normal hours.");



action.setRedirectURL(current);


Should have mention I'm setting u_startedwork to 17:00 and u_endedwork to 19:00 - i.e. I should see 1 hour of "normal hours".



Line 1 correctly displays 17:00 to 19:00, but if I don't use getDisplayValue it shows 06:00 to 08:00, which is what I assume it is using on line 11, resulting in the output being 2 "normal hours".


Try this instead:



var dur = dc.calcScheduleDuration(current.u_startedwork.getDisplayValue(), current.u_endedwork.getDisplayValue());



I've never used this method before, so I don't know what that'll do to it, but its worth a shot since the function appears to want a string: DurationCalculator - ServiceNow Wiki


The SN Nerd
Giga Sage
Giga Sage

I've recently done a lot of research and work on GlideDateTime Time Zones and offer some code and information:



The Difference Between GMT and UTC

Greenwich Mean Time (GMT) is often interchanged or confused with Coordinated Universal Time (UTC). But GMT is a time zone and UTC is a time standard.


Although GMT and UTC share the same current time in practice, there is a basic difference between the two:


  • GMT is a time zone officially used in some European and African countries. The time can be displayed using both the 24-hour format (0 - 24) or the 12-hour format (1 - 12 am/pm).
  • UTC is not a time zone, but a time standard that is the basis for civil time and time zones worldwide. This means that no country or territory officially uses UTC as a local time.

Source:GMT versus UTC



I recently had a requirement to determine if a lead time of 5 days was given for changes via the UI.
This was tricky and the only way I could work it out was to apply offset as suggested.
I also used GlideSchedule to work it out in terms of business days.



var clientStart = '21-01-2016 14:12:43';


var clientLead = '5 00:00:00';


var plannedStart = new GlideDateTime( clientStart );


//The client give us the value in the users time zone, we need it in GMT


plannedStart.add(plannedStart.getTZOffset() * -1);


var leadTime = new GlideDuration(clientLead);


gs.info( isLeadTimeGiven(plannedStart , leadTime) );


     


function isLeadTimeGiven(plannedStart, leadTime) {


      gs.addInfoMessage("isLeadTimeGiven");


      var now = new GlideDateTime();


      var schedule = new GlideSchedule();


      schedule.load('5f0963020f4d9e00703ecd8ce1050eff'); //Business Days Schedule


      var duration = schedule.duration(now, plannedStart);


      return ( duration.getDurationValue() > leadTime.getDurationValue() );


}



I also recently posted this code for someone else in another thread to display a time in any TZ in the given format



function getStringDateInTZ(gdt, tzString) {  


var tz = Packages.java.util.TimeZone.getTimeZone(tzString);  


gdt.setTZ(tz);  


var dateString = gs.getMessage(  


"{0}/{1}/{2} {3} {4}",[  


gdt.getDayOfMonthLocalTime(),  


gdt.getMonthLocalTime(),  


gdt.getYearLocalTime(),  


gdt.getLocalTime().toString().split(' ')[1],  


tzString  


]);  


return dateString;  


}  



ServiceNow Nerd
ServiceNow Developer MVP 2020-2022
ServiceNow Community MVP 2019-2022

You can create a GlideDateTime in the timezone you need by TZ Name using this:



        var cal = new GlideDateTime().getCalendarInTimeZone('EST');
      var dt = new GlideDateTime(cal.getTime());