On a recent project, I needed to copy some date-time fields from one record to another.
I was using a server-based script include to do the copying, and assumed that I would be fine with a:
newRecord.created_at = oldRecord.getValue(‘created_at’) kind of construction.
What I found in practice though was that the date-time field on the copied record was 6 hours different than the field that had been copied from the original record.
This struck me as likely being due to a GMT vs local time kind of issue. That didn’t make a ton of sense given that we should just be copying one number from the back end to another field, also on the back end. Logically, I wasn’t expecting it to do any kind of changing of either of those two numbers to account for the user’s time setting, but apparently I was wrong.
Construction like this:
newRecord.created_at = oldRecord.getDisplayValue(‘created_at’)
Is returning a new record where the date-time field matches the original.
My best guess at this point is that ServiceNow runs some kind of middleware anytime you save a date-time (even on the back end) which takes whatever the user inputs and converts it to GMT.
In the original code, this meant that I was pulling GMT out of the database on the original record, and then that time was being shifted 6 hours before it was saved on the new record.
By getting the display value of the old record, we shifted the GMT time to local time, and then passed the local time to the middleware function which shifted it back to GMT before saving the new record to the database.
In short, any time you want to copy date-times, you need to use a .getDisplayValue() on the field you’re copying in order to have the value being saved in the new field match up with the old field.