4

I keep getting:

Invalid date/time: 2018-06-10T12:34:15.29

Received from endpoint as and is stored in endpointResponse:

2018-06-10T12:34:15.290000

I process by:

string lastDate0String = endpointResponse.client[0].lastUpdated;
string lastDate1String = endpointResponse.client[1].lastUpdated;
string lastDate0 = lastDate0String.left(22);
string lastDate1 = lastDate1String.left(22);

dateTime lastUpdated1 = Datetime.valueOf(lastDate0);
dateTime lastUpdated2 = Datetime.valueOf(lastDate1);

if (lastUpdated1 > lastUpdated2) {
    //1 is newer than 2
}
else {
    //2 is newer than 1  
}

I get the error from:

dateTime lastUpdated1 = Datetime.valueOf(lastDate0);

I found the following article for Dataloader/API proper datetime formatting which I would think would be the same, but cannot find specific formatting examples for Apex. I'm obviously getting this wrong.

https://help.salesforce.com/articleView?id=Data-Loader-Import-data-for-Date-or-Date-Time-field-1327108684799&language=en_US&type=1

3 Answers 3

4

I don't know why JSON dates are parseable with different formats, but they are. You can manage this by constructing and then deserializing JSON that contains your date string(s). There's probably a more elegant way to do this with your incoming data structures than the below, but this is illustrative.

String dateString = ('{ "thedate": "2018-06-10T12:34:15.29"}');
Map<String, DateTime> mockMap;

mockMap = (Map<String, DateTime>)JSON.deserialize(dateString, Map<String, DateTime>.class);
System.debug(mockMap.get('thedate'));

This yields

15:58:05:005 USER_DEBUG [5]|DEBUG|2018-06-10 12:34:15

As Adrian found, the Map isn't actually what makes the deserialization work - it's the presence of double quotes around the DateTime value.

You can also use this approach if you deserialize incoming JSON content structures into an Apex class with members of type DateTime.

4
  • 1
    Hmm strange. When I tried it with just the input string, I got 2018-01-01 00:00:00. I guess you had to wrap it in double quotes.
    – Adrian Larson
    Jun 28, 2018 at 20:02
  • That is weird, I was able to confirm this.
    – S.B.
    Jun 28, 2018 at 20:04
  • I found the same thing, which made me go for the Map. The same approach should work if deserializing Apex classes - I have a live integration that works that way.
    – David Reed
    Jun 28, 2018 at 20:05
  • 1
    You don't need a map at all. You just need the value to be wrapped in double quotes.
    – Adrian Larson
    Jun 28, 2018 at 20:07
6

I played around with the standard methods and wasn't able to find anything which would work for your format, but it's simple enough to get working with regular expressions. Here's an example of how that might look:

system.debug(parse('2018-06-10T12:34:15.29'));
static Datetime parse(String input)
{
    Matcher m = Pattern.compile(
        '(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})\\.(\\d+)'
    ).matcher(input);
    return !m.find() ? null : Datetime.newInstanceGmt(
        Date.newInstance(
            Integer.valueOf(m.group(1)),
            Integer.valueOf(m.group(2)),
            Integer.valueOf(m.group(3))
        ),
        Time.newInstance(
            Integer.valueOf(m.group(4)),
            Integer.valueOf(m.group(5)),
            Integer.valueOf(m.group(6)),
            Integer.valueOf(m.group(6))
        )
    );
}

If you run this script in Execute Anonymous, you should get the following log:

USER_DEBUG [1]|DEBUG|2018-06-10 12:34:15


Just a note that the reason serialization did not work for me is I initially tried:

Datetime value = (Datetime)JSON.deserialize('2018-06-10T12:34:15.29', Datetime.class);

But the value to be parsed needs to be quote wrapped:

Datetime value = (Datetime)JSON.deserialize('"2018-06-10T12:34:15.29"', Datetime.class);
1

Appreciate the answers, probably going to go with MAP method provided by David Reed for readability, but I also got the following working using only SF methods.

What I really needed for my answer was to know what 1. Milliseconds are not valid 2. The T is not valid.

string lastDate0 = lastDate0String.left(19);
string lastDate1 = lastDate1String.left(19);
lastDate0 = lastDate0.replace('T', ' ');
lastDate1 = lastDate1.replace('T', ' ');

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .