Date range queries fail when developers pass JavaScript Date objects directly to addQuery() or forget that ServiceNow stores all dates in UTC while displaying them in the user's timezone. The platform requires GlideDateTime objects for reliable date comparisons, and you must explicitly handle the UTC conversion or your queries will return records from different date boundaries than expected. Most developers get burned by this when their date range queries work in development but fail in production environments with different timezones.

When to use this

  • Processing records created or modified within specific date boundaries in Business Rules or Scheduled Jobs
  • Building custom reporting datasets that need precise date filtering with multiple field access per record
  • Data cleanup or migration scripts where you need to identify records within a specific timeframe
  • SLA calculations or escalation logic that depends on record creation timestamps

When NOT to use this

  • Don't use this when you only need record counts — use GlideAggregate with addAggregate('COUNT') instead
  • Don't iterate date range queries inside loops — you'll create N+1 query problems that destroy performance at scale
  • Don't use this in client-side scripts — dates are unreliable across browser timezones, use GlideAjax to call server-side logic
  • Don't query massive date ranges without setLimit() — you'll hit transaction timeout limits and impact system performance

Key behaviors and gotchas

  • ServiceNow stores all datetime fields in UTC regardless of user timezone — always use GlideDateTime with explicit UTC conversion
  • The sys_created_on field is indexed on all tables — use it for the primary date filter to get optimal query performance
  • Date range queries with >= and <= are inclusive on both ends — use < for exclusive end boundaries
  • Domain separation affects date range queries — records in different domains won't appear unless you have cross-domain read access
  • ACL restrictions apply to date range queries — users can only see records they have table-level read access to
  • Always call toString() on GlideElement values when building return objects — raw GlideElements cause serialization issues
⚠️

JavaScript Date.toISOString() creates dates in UTC, but if you pass that string directly to addQuery(), ServiceNow interprets it in the system timezone. Always use GlideDateTime.setValueUTC() to ensure consistent timezone handling across different ServiceNow instances.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime