Scripted REST ‐ Validating Date Formats - ben-vargas/servicenow-wiki GitHub Wiki
This article explains how to validate date and date/time values within a ServiceNow Scripted REST API, ensuring that the provided input matches the expected format based on the user's locale settings. This is crucial for handling data correctly when receiving data from external systems.
The Challenge
When building Scripted REST APIs, you often receive date and date/time values from external systems. These systems might use different date formats than your ServiceNow instance. To ensure data consistency, you need to validate that incoming date values adhere to the correct format based on the user's locale settings before processing the request.
The Solution
The solution involves using Java's SimpleDateFormat
class to parse incoming date strings and validate that they match the expected format using gs.getDateTimeFormat()
. This allows for dynamic date validation based on the user settings.
Code Snippets:
Here's the code snippet for validating a date/time string:
function validateDateFormat(dateChk) {
try {
var simplified_date = new Packages.java.text.SimpleDateFormat();
simplified_date.setLenient(false);
simplified_date.applyPattern(gs.getDateTimeFormat());
simplified_date.parse(dateChk);
return true;
} catch (err) {
return false;
}
}
Explanation:
-
function validateDateFormat(dateChk)
:- This function takes a date string (
dateChk
) as input and returnstrue
if the format is valid,false
otherwise.
- This function takes a date string (
-
var simplified_date = new Packages.java.text.SimpleDateFormat();
:- Creates an instance of Java's
SimpleDateFormat
class to handle date parsing and formatting.
- Creates an instance of Java's
-
simplified_date.setLenient(false);
:- Sets the
SimpleDateFormat
to be non-lenient, meaning it will strictly adhere to the provided format. This prevents it from accepting dates that are not valid or might be a different format.
- Sets the
-
simplified_date.applyPattern(gs.getDateTimeFormat());
:- Applies the date/time format pattern from ServiceNow using
gs.getDateTimeFormat()
, which is a user specific value.
- Applies the date/time format pattern from ServiceNow using
-
simplified_date.parse(dateChk);
:- Attempts to parse the input date string (
dateChk
) using the set pattern. If parsing is successful, it means the format is valid.
- Attempts to parse the input date string (
-
try { ... } catch (err) { ... }
:- The
try...catch
block handles theparse()
method exceptions, as they occur when the input string cannot be parsed. - If parsing fails, the function returns
false
. If it is successful, it returnstrue
.
- The
Example Usage within a Scripted REST API:
Here’s an example of how to use this function within a Scripted REST API resource, specifically when processing input of a glide_date_time
field:
// Assuming body is a JSON object with the input
// And FIELDS is an object defining the schema of what is being input.
else if (FIELDS[key].type == 'glide_date_time') {
try {
var simplified_date = new Packages.java.text.SimpleDateFormat();
simplified_date.setLenient(false);
simplified_date.applyPattern(gs.getDateTimeFormat());
var mydate = simplified_date.parse(body[key]);
changeGR[key] = body[key];
}
catch (err) {
var bad_field = {};
bad_field.field = key;
bad_field.info = 'Date not in valid format: ' + body[key] + ' -- Expecting: ' + gs.getDateTimeFormat();
invalid_fields.push(bad_field);
}
}
Explanation:
else if (FIELDS[key].type == 'glide_date_time') { ... }
- This logic checks the type of the field that is being processed by the API.
try { ... } catch (err) { ... }
:- The
try...catch
block handles the parsing. - If parsing is successful, then the
body[key]
value is assigned to the GlideRecordchangeGR[key]
property. - If parsing fails:
* The
bad_field
object is created and populated with the failed field name, and an error message with the expected date format. * Thebad_field
object is pushed into an array ofinvalid_fields
for later processing.
- The
Best Practices
- Error Handling: Always wrap date parsing within a
try...catch
block to gracefully handle invalid date formats and return meaningful error messages. - Locale Awareness: Use
gs.getDateTimeFormat()
to dynamically fetch the appropriate format, making your code locale-aware. - Type Checking: Verify the data type in
FIELDS[key].type
, especially if your API handles a variety of input types. - Clear Error Messages: Provide clear error messages that specify the expected date format, helping users correct their inputs.
- Date/Time vs Date: If you are only expecting a date value, you can use
gs.getDateFormat()
instead ofgs.getDateTimeFormat()
. - Input Sanitization: Ensure the input values are sanitized before using the
SimpleDateFormat
as it is an external java class.
When to Use This Method
- When you receive date and/or date/time values through a Scripted REST API.
- When you need to validate that the date format adheres to user settings.
- When you need to return meaningful error messages if the date formatting is not correct.
- When you need to ensure only valid dates are used when creating or updating records.
Additional Considerations
- Time Zones: If you're handling time zones, consider using
GlideDateTime
and it's conversion methods to ensure correct representation of timezones. - Asynchronous Processing: If you have a large number of fields, consider optimizing for performance by validating in an asynchronous process.
- Script Includes: You can refactor the code into a Script Include for easier reuse across multiple Scripted REST APIs.
Conclusion
By using the Java SimpleDateFormat
class in conjunction with gs.getDateTimeFormat()
, you can implement robust date and date/time validation in your ServiceNow Scripted REST APIs. This approach will help ensure that you process date values correctly, according to your users locale, prevent data inconsistencies, and provide helpful error messages for debugging. Always test your APIs thoroughly to ensure proper functionality in various scenarios.