Built something you're proud of? Tell the story. A quick G2 review of App Engine or Build Agent helps other developers see what's possible on ServiceNow. Share your experience.

How to get the time and date in CET time zone in scoped application

Sai25
Tera Guru

Hi All,

I would like the date and time to be converted in Scoped application below code is not working can you please help me.

var grIncident = new GlideRecord('incident');
if (grIncident.get('sys_id', 'e8bfe5eac380cb9896985630a00131a2')) {
    var gdt = new GlideDateTime(grIncident.opened_at);
    var gsdt = new GlideScheduleDateTime(gdt);
    gsdt.setTimeZone("CET");
    var cetTime = gsdt.getGlideDateTime().getDisplayValue();
    gs.info("Incident opened time in CET: " + cetTime );

}
The above Incident record created on the 2026-04-07 21:15:06 and output I am getting is Incident opened time in CET: 2026-04-07 19:15:06 (Actually it should be 17:45:06)
 
 
Thanks,
Sai.
1 ACCEPTED SOLUTION

Ankur Bawiskar
Tera Patron

@Sai25 

this works in scoped app

var strConvertedDateTime = new GlideScheduleDateTime(new GlideDateTime()).convertTimeZone("UTC", "IST");
var gdtConvertedDateTime = new GlideDateTime(strConvertedDateTime)

gs.info("Converted Time: "+gdtConvertedDateTime);

55.png

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader

View solution in original post

14 REPLIES 14

Pavan Srivastav
ServiceNow Employee

Hello Sai,

 

There are two separate issues here — one is a wrong API choice for timezone conversion in scoped apps, and the other explains why you are getting an unexpected offset.


Issue 1 — GlideScheduleDateTime is the Wrong API for Timezone Conversion

GlideScheduleDateTime is designed for schedule-based time calculations (working hours, SLAs), not straightforward timezone conversions. It is also not reliably available in all scoped app contexts.

The correct API for timezone conversion in a scoped application is GlideDateTime with getUserTimezone or using GlideTimeZone via the DateTimeUtil approach — but the simplest and most reliable method in scoped context is:

var grIncident = new GlideRecord('incident');
if (grIncident.get('sys_id', 'e8bfe5eac380cb9896985630a00131a2')) {

    // Get the raw UTC value from the field
    var gdtUTC = new GlideDateTime();
    gdtUTC.setValue(grIncident.getValue('opened_at')); // getValue gives UTC string

    // Convert to target timezone using GlideDateTime's built-in method
    var formatter = new GlideDateTime();
    formatter.setValue(gdtUTC.getValue());

    // setTZ accepts IANA timezone names
    formatter.setTZ(new Packages.java.util.TimeZone.getTimeZone('Europe/Paris')); // CET = Europe/Paris

    gs.info('Incident opened time in CET: ' + formatter.getDisplayValue());
}

Issue 2 — Why You Are Getting the Wrong Offset

Your record was created at 2026-04-07 21:15:06 and you expected 22:15:06 CET (UTC+1) or 23:15:06 CEST (UTC+2), but you got 19:15:06 which is actually going backwards — this means the API was applying an offset in the wrong direction or using a wrong base timezone.

The core problem is that grIncident.opened_at when passed directly into new GlideDateTime() may be returning the display value in the instance's local timezone rather than raw UTC, causing a double-offset calculation.

Always use getValue() to get the raw UTC string:

// ❌ Wrong — may pass display value (already offset from UTC)
var gdt = new GlideDateTime(grIncident.opened_at);

// ✅ Correct — gets raw UTC value guaranteed
var gdt = new GlideDateTime();
gdt.setValue(grIncident.getValue('opened_at'));

Issue 3 — CET vs CEST

April 7 2026 is in British Summer Time / Central European Summer Time territory. CET is UTC+1 in winter, but in April Europe uses CEST which is UTC+2. If your record is 21:15:06 UTC, the correct CET/CEST display should be 23:15:06 CEST.

Using the IANA name Europe/Paris or Europe/Berlin automatically handles the DST switch, whereas hardcoding "CET" as a string does not — it stays at UTC+1 year-round.


Complete Corrected Script

var grIncident = new GlideRecord('incident');
if (grIncident.get('sys_id', 'e8bfe5eac380cb9896985630a00131a2')) {

    // Step 1 — Get raw UTC value (never use field reference directly)
    var utcValue = grIncident.getValue('opened_at');
    gs.info('Raw UTC value from record: ' + utcValue);

    // Step 2 — Load into GlideDateTime as UTC
    var gdtUTC = new GlideDateTime();
    gdtUTC.setValue(utcValue);
    gs.info('Confirmed UTC time: ' + gdtUTC.getDisplayValue());

    // Step 3 — Convert to CET/CEST using IANA timezone name
    // Europe/Paris and Europe/Berlin both honour CET/CEST DST automatically
    var javaTimeZone = Packages.java.util.TimeZone.getTimeZone('Europe/Paris');
    gdtUTC.setTZ(javaTimeZone);

    // Step 4 — Display converted time
    var cetTime = gdtUTC.getDisplayValue();
    gs.info('Incident opened time in CET/CEST: ' + cetTime);
}

Expected output for your record:

Raw UTC value from record:      2026-04-07 21:15:06
Confirmed UTC time:             2026-04-07 21:15:06
Incident opened time in CET/CEST: 2026-04-07 23:15:06

Why Each Change Was Made

Problem Old code Fixed code
Wrong API for scoped timezone conversion GlideScheduleDateTime GlideDateTime.setTZ()
Possible double-offset from display value grIncident.opened_at grIncident.getValue('opened_at')
DST not handled — fixed UTC+1 year-round "CET" string 'Europe/Paris' IANA name
Offset applied in wrong direction Base timezone ambiguous Explicit UTC load via setValue()

Hi Pavan,

 

getting the below error while running the code.

 

Error Description: Use of Packages calls is not permitted in scoped applications,

Hello Sai,

 

There are two separate issues here — one is a wrong API choice for timezone conversion in scoped apps, and the other explains why you are getting an unexpected offset.


Issue 1 — GlideScheduleDateTime is the Wrong API for Timezone Conversion

GlideScheduleDateTime is designed for schedule-based time calculations (working hours, SLAs), not straightforward timezone conversions. It is also not reliably available in all scoped app contexts.

The correct API for timezone conversion in a scoped application is GlideDateTime with getUserTimezone or using GlideTimeZone via the DateTimeUtil approach — but the simplest and most reliable method in scoped context is:

var grIncident = new GlideRecord('incident');
if (grIncident.get('sys_id', 'e8bfe5eac380cb9896985630a00131a2')) {

    // Get the raw UTC value from the field
    var gdtUTC = new GlideDateTime();
    gdtUTC.setValue(grIncident.getValue('opened_at')); // getValue gives UTC string

    // Convert to target timezone using GlideDateTime's built-in method
    var formatter = new GlideDateTime();
    formatter.setValue(gdtUTC.getValue());

    // setTZ accepts IANA timezone names
    formatter.setTZ(new Packages.java.util.TimeZone.getTimeZone('Europe/Paris')); // CET = Europe/Paris

    gs.info('Incident opened time in CET: ' + formatter.getDisplayValue());
}

Issue 2 — Why You Are Getting the Wrong Offset

Your record was created at 2026-04-07 21:15:06 and you expected 22:15:06 CET (UTC+1) or 23:15:06 CEST (UTC+2), but you got 19:15:06 which is actually going backwards — this means the API was applying an offset in the wrong direction or using a wrong base timezone.

The core problem is that grIncident.opened_at when passed directly into new GlideDateTime() may be returning the display value in the instance's local timezone rather than raw UTC, causing a double-offset calculation.

Always use getValue() to get the raw UTC string:

// ❌ Wrong — may pass display value (already offset from UTC)
var gdt = new GlideDateTime(grIncident.opened_at);

// ✅ Correct — gets raw UTC value guaranteed
var gdt = new GlideDateTime();
gdt.setValue(grIncident.getValue('opened_at'));

Issue 3 — CET vs CEST

April 7 2026 is in British Summer Time / Central European Summer Time territory. CET is UTC+1 in winter, but in April Europe uses CEST which is UTC+2. If your record is 21:15:06 UTC, the correct CET/CEST display should be 23:15:06 CEST.

Using the IANA name Europe/Paris or Europe/Berlin automatically handles the DST switch, whereas hardcoding "CET" as a string does not — it stays at UTC+1 year-round.


Complete Corrected Script

var grIncident = new GlideRecord('incident');
if (grIncident.get('sys_id', 'e8bfe5eac380cb9896985630a00131a2')) {

    // Step 1 — Get raw UTC value (never use field reference directly)
    var utcValue = grIncident.getValue('opened_at');
    gs.info('Raw UTC value from record: ' + utcValue);

    // Step 2 — Load into GlideDateTime as UTC
    var gdtUTC = new GlideDateTime();
    gdtUTC.setValue(utcValue);
    gs.info('Confirmed UTC time: ' + gdtUTC.getDisplayValue());

    // Step 3 — Convert to CET/CEST using IANA timezone name
    // Europe/Paris and Europe/Berlin both honour CET/CEST DST automatically
    var javaTimeZone = Packages.java.util.TimeZone.getTimeZone('Europe/Paris');
    gdtUTC.setTZ(javaTimeZone);

    // Step 4 — Display converted time
    var cetTime = gdtUTC.getDisplayValue();
    gs.info('Incident opened time in CET/CEST: ' + cetTime);
}

Expected output for your record:

Raw UTC value from record:      2026-04-07 21:15:06
Confirmed UTC time:             2026-04-07 21:15:06
Incident opened time in CET/CEST: 2026-04-07 23:15:06

Why Each Change Was Made

Problem Old code Fixed code
Wrong API for scoped timezone conversion GlideScheduleDateTime GlideDateTime.setTZ()
Possible double-offset from display value grIncident.opened_at grIncident.getValue('opened_at')
DST not handled — fixed UTC+1 year-round "CET" string 'Europe/Paris' IANA name
Offset applied in wrong direction Base timezone ambiguous Explicit UTC load via setValue()

Hi Pavan,

Trying but again packages error.

 

Background message, type:error, message: Use of Packages calls is not permitted in scoped applications