Dates and DateTimes don’t always play nicely when you’re trying to push them through from environment to environment. You often have to mess about with them a bit to shoehorn them in and out of Salesforce.
I’m going to look here at how you get them to/from Javascript in the case of Visualforce remoting and then to/from JSON Strings if you’re integrating to another service where you need to use REST. There will no doubt be other ways to accomplish this and other scenerios but these are common use cases so this is more a starter for 10.
Javascript to Salesforce via Visualforce Remoting
Let’s begin by looking at going from Javascript to Salesforce via Visualforce Remoting.
Date example:
Javascript in a VF Page:
var dt = new Date(); console.log('dt=' + dt.toUTCString()); Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.RemoteController.sendDate}', dt.toUTCString(), function(result, event) { if (event.status) { console.log('result=' + result); } } );
Apex Controller Methods:
@RemoteAction public static String sendDate(Date dt) { String r = 'sendDate: ' + dt; return r; }
Results:
dt=Wed, 21 Sep 2016 18:40:43 GMT result=sendDate: 2016-09-21 18:40:43
Strangely, you’ll notice the resulting date still has the time element preserved when you emit it. It shouldn’t be an issue since in Salesforce you’ll be throwing an instance of Date around. Just be careful when sending Dates back that were constructed in this way. It would probably be safer to use a DateTime in the remoting method and the use date() to return the date portion if that’s what you want.
DateTime example:
Javascript in a VF Page:
var dt = new Date(); console.log('dt=' + dt.toUTCString()); Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.RemoteController.sendDateTime}', dt.toUTCString(), function(result, event) { if (event.status) { console.log('result=' + result); } } );
Apex Controller Methods:
@RemoteAction public static String sendDateTime(DateTime dt) { String r = 'sendDateTime: ' + dt; return r; }
Results:
dt=Wed, 21 Sep 2016 18:40:43 GMT result=sendDateTime: 2016-09-21 18:40:43
Salesforce to Javascript via Visualforce Remoting
Date example:
Javascript in a VF Page:
Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.RemoteController.getDate}', function(result, event) { if (event.status) { var d = new Date(result); console.log('d=' + d); } } );
Apex Controller Methods:
@RemoteAction public static Date getDate() { return System.today(); }
Results:
d=Wed Sep 21 2016 01:00:00 GMT+0100 (BST)
DateTime example:
Javascript in a VF Page:
Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.RemoteController.getDateTime}', function(result, event) { if (event.status) { var dt = new Date(result); console.log('dt=' + dt); } } );
Apex Controller Methods:
@RemoteAction public static DateTime getDateTime() { return System.now(); }
Results:
dt=Wed Sep 21 2016 20:16:17 GMT+0100 (BST)
Salesforce to JSON String
Date Example:
Apex code:
Date d = System.today(); String ds = JSON.serialize(d); System.debug('d=' + d); System.debug('ds=' + ds);
Results:
d=2016-09-21 00:00:00 ds="2016-09-21"
DateTime Example:
Apex code:
DateTime dt = System.now(); String dts = JSON.serialize(dt); System.debug('ds=' + dt); System.debug('dts=' + dts);
Results:
ds=2016-09-21 18:51:25 dts="2016-09-21T18:51:25.234Z"
JSON String to Salesforce
Now this is where the fun begins! You’d think that if you serialize a date or datetime, you can simply deserialize it back again wouldn’t you? WRONG!
Date Example:
This won’t work:
Date d = System.today(); String ds = JSON.serialize(d); Date d2 = (Date)JSON.deserializeUntyped(ds); System.debug('d=' + d); System.debug('ds=' + ds); System.debug('d2=' + d2);
Nor will this:
Date d = System.today(); String ds = JSON.serialize(d); Date d2 = Date.valueOf(ds); System.debug('d=' + d); System.debug('ds=' + ds); System.debug('d2=' + d2);
You need to do this:
Date d = System.today(); String ds = JSON.serialize(d); Date d2 = Date.valueOf(ds.replace('"', '')); System.debug('d=' + d); System.debug('ds=' + ds); System.debug('d2=' + d2);
Results:
d=2016-09-21 00:00:00 ds="2016-09-21" d2=2016-09-21 00:00:00
DateTime Example:
This won’t work:
DateTime dt = System.now(); String dts = JSON.serialize(dt); DateTime dt2 = (DateTime)JSON.deserializeUntyped(dts); System.debug('dt=' + dt); System.debug('dts=' + dts); System.debug('dt2=' + dt2);
Nor will this:
DateTime dt = System.now(); String dts = JSON.serialize(dt); DateTime dt2 = DateTime.valueOf(dts); System.debug('dt=' + dt); System.debug('dts=' + dts); System.debug('dt2=' + dt2);
You need to do this:
DateTime dt = System.now(); String dts = JSON.serialize(dt); DateTime dt2 = DateTime.valueOf(dts.replace('"', ' ').replace('T', ' ')); System.debug('dt=' + dt); System.debug('dts=' + dts); System.debug('dt2=' + dt2);
Results:
dt=2016-09-21 19:01:27 dts="2016-09-21T19:01:27.217Z" dt2=2016-09-21 18:01:27
As I said, there are more ways to crack a nut and there are no doubt more scenarios but hopefully this will help avoid some of the confusion.