Date handling is one of the most common sources of bugs and runtime errors in NetSuite SuiteScript development. Whether you are building a Suitelet, a User Event Script, or a Scheduled Script, improperly formatted date values can cause silent failures, validation errors, and unexpected record behavior. This guide covers the most frequent date formatting issues, explains why they occur, and shows you exactly how to fix them.
Why Date Formatting Matters in NetSuite
NetSuite is a multi-tenant platform used across dozens of countries, each with different regional date formats. Internally, NetSuite stores dates as JavaScript Date objects or ISO 8601 strings, but when you set a field value on a record, NetSuite expects the date to match the user’s or company’s locale setting. If the format does not match, NetSuite either silently ignores the value, stores an empty date, or throws a validation error at submit time.
Common Error #1 β Wrong Date Format String
The most frequent mistake is passing a date string in the wrong format. For example, if your NetSuite account is configured for the MM/DD/YYYY format (US locale) and you pass a value like 2024-05-15 (ISO format), the field will be set to empty or throw an error.
// β WRONG β ISO format will NOT work when locale expects MM/DD/YYYY
record.setValue({
fieldId: 'trandate',
value: '2024-05-15'
});
// β
CORRECT β Use a JavaScript Date object instead
record.setValue({
fieldId: 'trandate',
value: new Date(2024, 4, 15) // Month is 0-indexed: 4 = May
});
The safest approach is always to pass a native JavaScript Date object to setValue() for date fields. NetSuite handles the locale-specific formatting internally when you use a Date object.
Common Error #2 β Using a String Instead of a Date Object
Many developers try to build a date string manually and pass it to setValue(). While this can work in specific locales, it breaks the moment the account is used in a different region or if the administrator changes the company date format. Always convert strings to Date objects first.
// β RISKY β Hard-coded string format breaks across locales
record.setValue({
fieldId: 'startdate',
value: '05/15/2024'
});
// β
CORRECT β Parse your string safely using the N/format module
var format = require('N/format');
var parsedDate = format.parse({
value: '05/15/2024',
type: format.Type.DATE
});
record.setValue({
fieldId: 'startdate',
value: parsedDate
});
Common Error #3 β Off-by-One Month (JavaScript Month Indexing)
JavaScript’s Date constructor uses zero-based month indexing: January = 0, February = 1, …, December = 11. This is a very common source of bugs where dates appear one month off from what was intended.
// β WRONG β This creates June 15, not May 15
var wrongDate = new Date(2024, 5, 15); // Month 5 = June
// β
CORRECT β May is month index 4
var correctDate = new Date(2024, 4, 15); // Month 4 = May
// β
ALTERNATIVE β Use Date.UTC for clarity
var utcDate = new Date(Date.UTC(2024, 4, 15)); // May 15, 2024 UTC
A good practice is to add a comment next to every new Date() call that notes the month name to avoid confusion during code reviews.
Common Error #4 β Timezone Offset Shifting the Date
NetSuite stores date-only fields (like trandate, startdate) without a time component, but JavaScript Date objects always include time and timezone information. If your server or browser is in a negative UTC offset timezone (e.g., UTC-5), passing new Date('2024-05-15') can result in the date being interpreted as May 14 in local time.
// β RISKY β Parsing ISO string can shift date in negative UTC timezones
var d = new Date('2024-05-15');
// In UTC-5, this becomes May 14, 2024 at 19:00 local time
// β
CORRECT β Use explicit year, month, day constructor (local time)
var d = new Date(2024, 4, 15); // Always May 15 in local time
// β
CORRECT β Or use format.parse() from N/format which is timezone-aware
var format = require('N/format');
var d = format.parse({ value: '05/15/2024', type: format.Type.DATE });
Common Error #5 β Reading a Date Field and Re-Setting It
When you use record.getValue() on a date field, NetSuite returns a JavaScript Date object. However, if you use record.getText(), it returns a locale-formatted string. Many developers mistakenly read the text value and then try to set it back, which can fail.
// β WRONG β getText() returns a locale string, setting it back can fail
var dateText = record.getText({ fieldId: 'trandate' }); // Returns "05/15/2024"
record.setValue({ fieldId: 'trandate', value: dateText }); // May fail
// β
CORRECT β Use getValue() which returns a Date object
var dateObj = record.getValue({ fieldId: 'trandate' }); // Returns Date object
record.setValue({ fieldId: 'trandate', value: dateObj }); // Works correctly
// β
If you need to manipulate the date, work with the Date object
var dateObj = record.getValue({ fieldId: 'trandate' });
dateObj.setDate(dateObj.getDate() + 30); // Add 30 days
record.setValue({ fieldId: 'trandate', value: dateObj });
Common Error #6 β Setting DateTime Fields Without Time Component
Some NetSuite fields are DATETIME type (not just DATE), such as lastmodifieddate or custom datetime fields. These fields require both a date and a time value. Passing a date-only string will cause an error or unexpected behavior.
var format = require('N/format');
// β WRONG β Passing date-only string to a DATETIME field
record.setValue({
fieldId: 'custfield_scheduled_time',
value: '05/15/2024'
});
// β
CORRECT β Use format.Type.DATETIMETZ or DATETIME
var dateTimeValue = format.parse({
value: '05/15/2024 10:30 am',
type: format.Type.DATETIME
});
record.setValue({
fieldId: 'custfield_scheduled_time',
value: dateTimeValue
});
Using N/format to Format Dates for Display
The N/format module provides two key methods for date handling: format.format() converts a Date object to a locale-formatted string, and format.parse() converts a locale-formatted string to a Date object. Use these when you need to display dates or when processing dates from external sources.
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/format', 'N/record', 'N/log'], function(format, record, log) {
function onRequest(context) {
// β
Convert a Date object to a display string
var today = new Date();
var displayDate = format.format({
value: today,
type: format.Type.DATE
});
log.debug({ title: 'Display Date', details: displayDate });
// Output: "05/27/2026" (in MM/DD/YYYY locale)
// β
Parse a user-provided date string back into a Date object
var inputString = '05/27/2026';
var parsedDate = format.parse({
value: inputString,
type: format.Type.DATE
});
// β
Now safely set it on a record
var rec = record.load({ type: record.Type.SALES_ORDER, id: 12345 });
rec.setValue({ fieldId: 'trandate', value: parsedDate });
rec.save();
}
return { onRequest: onRequest };
});
Handling Dates from External APIs and CSV Files
When receiving dates from REST APIs or CSV imports, dates typically arrive in ISO 8601 format (YYYY-MM-DD). Use a helper function to safely convert these to Date objects before setting them on records, avoiding any timezone or locale issues.
/**
* Safely parse an ISO date string (YYYY-MM-DD) into a local Date object.
* Avoids timezone shifting by using explicit year/month/day constructor.
*
* @param {string} isoString - Date string in YYYY-MM-DD format
* @returns {Date} Local Date object with no timezone offset
*/
function parseISODate(isoString) {
var parts = isoString.split('-');
var year = parseInt(parts[0], 10);
var month = parseInt(parts[1], 10) - 1; // Convert to 0-indexed
var day = parseInt(parts[2], 10);
return new Date(year, month, day);
}
// Usage:
var apiDateString = '2024-05-15'; // From external API
var safeDate = parseISODate(apiDateString);
record.setValue({
fieldId: 'trandate',
value: safeDate // β
Correctly set as May 15, 2024
});
Quick Reference: Date Field Best Practices
| Scenario | Recommended Approach |
|---|---|
| Set today’s date | record.setValue({ fieldId: 'trandate', value: new Date() }) |
| Set a specific date | new Date(year, monthIndex, day) β remember month is 0-indexed |
| Parse a locale string | Use format.parse({ value: str, type: format.Type.DATE }) |
| Format a date for display | Use format.format({ value: dateObj, type: format.Type.DATE }) |
| Parse an ISO string (YYYY-MM-DD) | Use the parseISODate() helper above β never new Date(isoString) |
| Read and re-set a date field | Always use getValue(), never getText() |
| Handle datetime fields | Use format.Type.DATETIME and include time component |
Debugging Date Issues
When troubleshooting date field issues, always log the value and its type before setting it on the record. Use N/log to inspect what JavaScript sees versus what you expect.
var log = require('N/log');
var myDate = new Date(2024, 4, 15);
log.debug({
title: 'Date Debug',
details: JSON.stringify({
value: myDate,
type: typeof myDate,
iso: myDate.toISOString(),
locale: myDate.toLocaleDateString()
})
});
// Output: {"value":"2024-05-15T00:00:00.000Z","type":"object","iso":"2024-05-15T00:00:00.000Z","locale":"5/15/2024"}
Check the Script Execution Log in NetSuite under Customization > Scripting > Script Execution Log to review these debug messages in real time. The log output shows you the exact value being passed, which immediately reveals format mismatches.
Summary
Date formatting issues in NetSuite SuiteScript almost always come down to three root causes: locale mismatch (passing a string in the wrong format), timezone offset (ISO string shifting the date by a day), or JavaScript month indexing (using new Date(2024, 5, 15) and getting June instead of May). By consistently using native Date objects with setValue(), leveraging the N/format module for string conversion, and using the parseISODate() helper for external API data, you can eliminate virtually all date-related bugs from your SuiteScript code.
For more SuiteScript module guides, visit the NetSuite SuiteScript Modules Complete Guide. To learn more about the N/format module specifically, see the N/format Module Guide.
Discover more from The NetSuite Pro
Subscribe to get the latest posts sent to your email.
Leave a Reply