The Trouble with Dates and Times

SundialDates 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.

Advertisements

Author, brainstormer, coder, dad, explorer, four chord trickster, gig goer, home worker, inquisitor, joker, knowledge seeker, likes: marmite, note scribbler, opinionator, poet, quite likes converse, roller skater, six music listener, tea drinker, urban dweller, vinyl spinner, word wrangler, x-factor hater, Yorkshireman (honorary), zombie slayer (lie).

Tagged with: , , , , ,
Posted in apex, code, force.com, salesforce
About Me
Product Services Developer at:
FinancialForce.com
All views expressed here are my own. More about me and contact details here.

Enter your email address to follow this blog and receive notifications of new posts by email.

Copyright (there isn’t any, feel free to reuse!)

CC0
To the extent possible under law, Tony Scott has waived all copyright and related or neighboring rights to MeltedWires.com Examples and Code Samples. This work is published from: United Kingdom.

%d bloggers like this: