Skip to Content

Date Calculation Utility

Reusable functions for common date and time calculations, business days, and formatting.

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

Script Code

JavaScript
1var DateCalculator = Class.create();
2DateCalculator.prototype = {
3
4  /**
5   * Add business days to a date
6   * @param {GlideDateTime} startDate - Starting date
7   * @param {number} days - Number of business days to add
8   * @param {string} scheduleId - Schedule sys_id or name (optional)
9   * @returns {GlideDateTime} Resulting date
10   */
11  addBusinessDays: function(startDate, days, scheduleId) {
12    scheduleId = scheduleId || '8-5 weekdays excluding holidays';
13
14    var schedule = new GlideSchedule(scheduleId);
15    var duration = new GlideDuration(days * 24 * 60 * 60 * 1000);  // Convert days to ms
16
17    var resultDate = new GlideDateTime(startDate);
18    resultDate = schedule.add(resultDate, duration);
19
20    return resultDate;
21  },
22
23  /**
24   * Calculate business days between two dates
25   * @param {GlideDateTime} startDate
26   * @param {GlideDateTime} endDate
27   * @param {string} scheduleId
28   * @returns {number} Number of business days
29   */
30  getBusinessDaysBetween: function(startDate, endDate, scheduleId) {
31    scheduleId = scheduleId || '8-5 weekdays excluding holidays';
32
33    var schedule = new GlideSchedule(scheduleId);
34    var duration = schedule.duration(startDate, endDate);
35
36    // Convert duration to days (assuming 8-hour workday)
37    var seconds = duration.getNumericValue();
38    var businessDays = seconds / (8 * 60 * 60);
39
40    return Math.round(businessDays * 10) / 10;  // Round to 1 decimal
41  },
42
43  /**
44   * Get calendar days between two dates
45   * @param {GlideDateTime} startDate
46   * @param {GlideDateTime} endDate
47   * @returns {number} Number of calendar days
48   */
49  getCalendarDaysBetween: function(startDate, endDate) {
50    var start = new GlideDateTime(startDate);
51    var end = new GlideDateTime(endDate);
52
53    var diff = GlideDateTime.subtract(start, end);
54    var days = diff.getNumericValue() / (1000 * 60 * 60 * 24);
55
56    return Math.abs(Math.round(days));
57  },
58
59  /**
60   * Check if a date is a weekend
61   * @param {GlideDateTime} date
62   * @returns {boolean}
63   */
64  isWeekend: function(date) {
65    var gdt = new GlideDateTime(date);
66    var dayOfWeek = gdt.getDayOfWeek();
67    return dayOfWeek === 1 || dayOfWeek === 7;  // Sunday = 1, Saturday = 7
68  },
69
70  /**
71   * Check if a date is a holiday
72   * @param {GlideDateTime} date
73   * @param {string} scheduleId
74   * @returns {boolean}
75   */
76  isHoliday: function(date, scheduleId) {
77    scheduleId = scheduleId || '8-5 weekdays excluding holidays';
78
79    var schedule = new GlideSchedule(scheduleId);
80    return !schedule.isInSchedule(date);
81  },
82
83  /**
84   * Get the next business day
85   * @param {GlideDateTime} date - Starting date
86   * @param {string} scheduleId
87   * @returns {GlideDateTime} Next business day
88   */
89  getNextBusinessDay: function(date, scheduleId) {
90    scheduleId = scheduleId || '8-5 weekdays excluding holidays';
91
92    var schedule = new GlideSchedule(scheduleId);
93    var nextDay = new GlideDateTime(date);
94    nextDay.addDaysLocalTime(1);
95
96    // Keep adding days until we find a business day
97    var maxAttempts = 10;  // Prevent infinite loop
98    var attempts = 0;
99
100    while (!schedule.isInSchedule(nextDay) && attempts < maxAttempts) {
101      nextDay.addDaysLocalTime(1);
102      attempts++;
103    }
104
105    return nextDay;
106  },
107
108  /**
109   * Format date for display
110   * @param {GlideDateTime} date
111   * @param {string} format - 'short', 'long', 'iso', 'custom'
112   * @returns {string} Formatted date string
113   */
114  formatDate: function(date, format) {
115    var gdt = new GlideDateTime(date);
116    format = format || 'short';
117
118    switch(format) {
119      case 'short':
120        return gdt.getDisplayValue();  // MM/DD/YYYY HH:mm:ss
121
122      case 'long':
123        return gdt.getDisplayValueWithoutTZ();  // Full format
124
125      case 'iso':
126        return gdt.getValue();  // YYYY-MM-DD HH:mm:ss
127
128      case 'date-only':
129        return gdt.getDate().getDisplayValue();  // MM/DD/YYYY
130
131      case 'time-only':
132        return gdt.getTime().getDisplayValue();  // HH:mm:ss
133
134      case 'custom':
135        // Custom format: "January 15, 2024 at 2:30 PM"
136        var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
137                         'July', 'August', 'September', 'October', 'November', 'December'];
138
139        var month = monthNames[gdt.getMonth() - 1];
140        var day = gdt.getDayOfMonth();
141        var year = gdt.getYear();
142        var hour = gdt.getHour();
143        var minute = gdt.getMinute();
144        var ampm = hour >= 12 ? 'PM' : 'AM';
145
146        hour = hour % 12;
147        hour = hour ? hour : 12;  // 0 should be 12
148        minute = minute < 10 ? '0' + minute : minute;
149
150        return month + ' ' + day + ', ' + year + ' at ' + hour + ':' + minute + ' ' + ampm;
151
152      default:
153        return gdt.getDisplayValue();
154    }
155  },
156
157  /**
158   * Get age in years, months, days from a date
159   * @param {GlideDateTime} date - Birth date or start date
160   * @returns {object} {years: number, months: number, days: number}
161   */
162  getAge: function(date) {
163    var start = new GlideDateTime(date);
164    var now = new GlideDateTime();
165
166    var years = now.getYear() - start.getYear();
167    var months = now.getMonth() - start.getMonth();
168    var days = now.getDayOfMonth() - start.getDayOfMonth();
169
170    // Adjust for negative days
171    if (days < 0) {
172      months--;
173      // Get days in previous month
174      var prevMonth = new GlideDateTime(now);
175      prevMonth.addMonthsLocalTime(-1);
176      var daysInPrevMonth = prevMonth.getDaysInMonth();
177      days += daysInPrevMonth;
178    }
179
180    // Adjust for negative months
181    if (months < 0) {
182      years--;
183      months += 12;
184    }
185
186    return {
187      years: years,
188      months: months,
189      days: days,
190      totalDays: this.getCalendarDaysBetween(start, now)
191    };
192  },
193
194  /**
195   * Check if date is within a date range
196   * @param {GlideDateTime} checkDate
197   * @param {GlideDateTime} startDate
198   * @param {GlideDateTime} endDate
199   * @returns {boolean}
200   */
201  isDateInRange: function(checkDate, startDate, endDate) {
202    var check = new GlideDateTime(checkDate);
203    var start = new GlideDateTime(startDate);
204    var end = new GlideDateTime(endDate);
205
206    return check.after(start) && check.before(end);
207  },
208
209  type: 'DateCalculator'
210};

How to Use

1. Create a new Script Include named 'DateCalculator' 2. Leave 'Client callable' unchecked 3. Copy the code above 4. Use in Business Rules or Background Scripts: var calc = new DateCalculator(); var dueDate = calc.addBusinessDays(new GlideDateTime(), 5); var daysBetween = calc.getBusinessDaysBetween(start, end); var formatted = calc.formatDate(new GlideDateTime(), 'custom');

Explore More Scripts

Browse our complete library of ServiceNow scripts

View All Scripts