Skip to Content

Date/Time Utilities

Reusable functions for date and time calculations and formatting.

#datetime #date #time #utilities #formatting #business-days #schedule

Script Code

JavaScript
1var DateTimeUtils = Class.create();
2DateTimeUtils.prototype = {
3
4  /**
5   * Add business days to a date (excludes weekends and holidays)
6   *
7   * @param {GlideDateTime} startDate - Starting date
8   * @param {number} days - Number of business days to add
9   * @param {string} scheduleId - (Optional) sys_id of schedule to use
10   * @returns {GlideDateTime} Calculated date
11   */
12  addBusinessDays: function(startDate, days, scheduleId) {
13    if (!startDate || !days) {
14      return startDate;
15    }
16
17    var schedule;
18    if (scheduleId) {
19      schedule = new GlideSchedule(scheduleId);
20    } else {
21      // Use default 8-5 schedule (sys_id for "8-5 weekdays excluding holidays")
22      schedule = new GlideSchedule('c6a2389e0a0a0b9b006cfc04227be354');
23    }
24
25    var gdt = new GlideDateTime(startDate);
26    var duration = new GlideDuration(days * 24 * 60 * 60 * 1000);  // Convert days to ms
27
28    var endDate = schedule.add(gdt, duration);
29    return endDate;
30  },
31
32  /**
33   * Calculate business days between two dates
34   *
35   * @param {GlideDateTime} startDate - Start date
36   * @param {GlideDateTime} endDate - End date
37   * @param {string} scheduleId - (Optional) sys_id of schedule to use
38   * @returns {number} Number of business days
39   */
40  getBusinessDaysBetween: function(startDate, endDate, scheduleId) {
41    if (!startDate || !endDate) {
42      return 0;
43    }
44
45    var schedule;
46    if (scheduleId) {
47      schedule = new GlideSchedule(scheduleId);
48    } else {
49      schedule = new GlideSchedule('c6a2389e0a0a0b9b006cfc04227be354');
50    }
51
52    var duration = schedule.duration(startDate, endDate);
53    var days = duration.getDayPart();
54    var hours = duration.getHourPart();
55
56    // Convert to decimal days
57    var totalDays = days + (hours / 24);
58    return totalDays;
59  },
60
61  /**
62   * Format date to user-friendly string
63   *
64   * @param {GlideDateTime} dateTime - Date to format
65   * @param {string} format - Format type: 'short', 'long', 'time', 'datetime'
66   * @returns {string} Formatted date string
67   */
68  formatDate: function(dateTime, format) {
69    if (!dateTime) {
70      return '';
71    }
72
73    var gdt = new GlideDateTime(dateTime);
74    format = format || 'short';
75
76    switch(format) {
77      case 'short':
78        // MM/DD/YYYY
79        return gdt.getDisplayValue().split(' ')[0];
80
81      case 'long':
82        // Month DD, YYYY
83        return gdt.getByFormat('MMMM dd, yyyy');
84
85      case 'time':
86        // HH:MM AM/PM
87        return gdt.getByFormat('hh:mm a');
88
89      case 'datetime':
90        // MM/DD/YYYY HH:MM AM/PM
91        return gdt.getByFormat('MM/dd/yyyy hh:mm a');
92
93      case 'iso':
94        // ISO 8601 format
95        return gdt.getValue();
96
97      default:
98        return gdt.getDisplayValue();
99    }
100  },
101
102  /**
103   * Get relative time description (e.g., "2 hours ago", "in 3 days")
104   *
105   * @param {GlideDateTime} dateTime - Date to compare
106   * @returns {string} Relative time description
107   */
108  getRelativeTime: function(dateTime) {
109    if (!dateTime) {
110      return '';
111    }
112
113    var now = new GlideDateTime();
114    var target = new GlideDateTime(dateTime);
115
116    var diff = gs.dateDiff(now.getValue(), target.getValue(), true);  // in seconds
117    var absDiff = Math.abs(diff);
118
119    var isPast = diff > 0;
120    var prefix = isPast ? '' : 'in ';
121    var suffix = isPast ? ' ago' : '';
122
123    // Calculate time units
124    var seconds = absDiff;
125    var minutes = Math.floor(seconds / 60);
126    var hours = Math.floor(minutes / 60);
127    var days = Math.floor(hours / 24);
128    var weeks = Math.floor(days / 7);
129    var months = Math.floor(days / 30);
130    var years = Math.floor(days / 365);
131
132    // Determine appropriate unit
133    if (years > 0) {
134      return prefix + years + (years === 1 ? ' year' : ' years') + suffix;
135    } else if (months > 0) {
136      return prefix + months + (months === 1 ? ' month' : ' months') + suffix;
137    } else if (weeks > 0) {
138      return prefix + weeks + (weeks === 1 ? ' week' : ' weeks') + suffix;
139    } else if (days > 0) {
140      return prefix + days + (days === 1 ? ' day' : ' days') + suffix;
141    } else if (hours > 0) {
142      return prefix + hours + (hours === 1 ? ' hour' : ' hours') + suffix;
143    } else if (minutes > 0) {
144      return prefix + minutes + (minutes === 1 ? ' minute' : ' minutes') + suffix;
145    } else {
146      return 'just now';
147    }
148  },
149
150  /**
151   * Check if date is within business hours
152   *
153   * @param {GlideDateTime} dateTime - Date to check
154   * @param {string} scheduleId - (Optional) sys_id of schedule to use
155   * @returns {boolean} True if within business hours
156   */
157  isBusinessHours: function(dateTime, scheduleId) {
158    if (!dateTime) {
159      return false;
160    }
161
162    var schedule;
163    if (scheduleId) {
164      schedule = new GlideSchedule(scheduleId);
165    } else {
166      schedule = new GlideSchedule('c6a2389e0a0a0b9b006cfc04227be354');
167    }
168
169    return schedule.isInSchedule(dateTime);
170  },
171
172  /**
173   * Get the next business day
174   *
175   * @param {GlideDateTime} startDate - Starting date (defaults to now)
176   * @returns {GlideDateTime} Next business day
177   */
178  getNextBusinessDay: function(startDate) {
179    var gdt = startDate ? new GlideDateTime(startDate) : new GlideDateTime();
180
181    // Add one day at a time until we find a business day
182    var maxAttempts = 10;  // Prevent infinite loop
183    var attempts = 0;
184
185    do {
186      gdt.addDaysLocalTime(1);
187      var dayOfWeek = gdt.getDayOfWeekLocalTime();
188      attempts++;
189
190      // 1 = Sunday, 7 = Saturday
191      if (dayOfWeek !== 1 && dayOfWeek !== 7) {
192        return gdt;
193      }
194    } while (attempts < maxAttempts);
195
196    return gdt;
197  },
198
199  type: 'DateTimeUtils'
200};

How to Use

1. Create a new Script Include 2. Set Name to "DateTimeUtils" 3. Leave "Client callable" unchecked 4. Copy the code above 5. Call from Business Rules, other Script Includes, or Background Scripts

Explore More Scripts

Browse our complete library of ServiceNow scripts

View All Scripts