Invalid date/time issue in Apex Code

apexdatetimeexceptionwebservices

I am working on a REST API integration class and it is passing a field called effectiveDate as part of the response. However, the data in the field is not consistent. Sometimes, it is passing the value as '1985-01-01 00:00:00.000' (UTC format) and sometimes it is passing the value as '1985-01-01T00:00:00' (ISO 8601 format). In my Response class, I have defined this field as shown below.

public String effectiveDate {get; set;}

In the apex class, I am trying to populate this date on the Asset object. Below is my code.

Datetime effectiveDt = Datetime.parse(wsResponse.effectiveDate);   //Statement throwing exception
template.effectiveDate = Date.newInstance(effectiveDt.yearGmt(), effectiveDt.monthGmt(), effectiveDt.dayGmt());

However, my statement with the Datetime.parse is throwing the following exception.

07:40:24:715 FATAL_ERROR System.TypeException: Invalid date/time: 1985-12-01T00:00:00

How can I modify my statement to accept the Datetime irrespective of whether it is coming in UTC format or ISO8601 format?

EDIT:
I have tried the following piece of code in execute anonymous window and I am getting the error message as [Line: 15, Column: 1
System.JSONException: Invalid format: "2019-01-01 11:50:55" is malformed at " 11:50:55"].

EDIT: Changed the month and date in the below dates.

String strDate1 = '2017-12-17T11:50:50.000Z';
String strDate2 = '2016-11-16 11:50:55';

Datetime date1 = (Datetime)JSON.deserialize('"' + strDate1 + '"',Datetime.class);
Datetime date2 = (Datetime)JSON.deserialize('"' + strDate2 + '"',Datetime.class);

System.debug('date 1 = ' + date1);
System.debug('date 2 = ' + date2); Date.newInstance(date1.yearGmt(),date1.monthGmt(),date1.dayGmt()));
System.debug('Date 2 = ' + Date.newInstance(date2.yearGmt(),date2.monthGmt(),date2.dayGmt()));

Output of debug log:

17:54:48:005 USER_DEBUG [7]|DEBUG|date 1 = 2017-01-01 00:00:00
17:54:48:005 USER_DEBUG [8]|DEBUG|date 2 = 2016-01-01 00:00:00
17:54:48:006 USER_DEBUG [9]|DEBUG|Date 1 = 2017-01-01 00:00:00
17:54:48:006 USER_DEBUG [10]|DEBUG|Date 2 = 2016-01-01 00:00:00

As you can see, the month and day are always coming as 01 instead of 12 and 11 that we are passing.

Any ideas?

Best Answer

deserializing your datetime (both utc & ISO) in datetime.class should solve the issue. JSON.desrialize('datetime' , Datetime.class);

i have tested both format in anynomous block and it is working fine.

Datetime effectiveDt = (Datetime) JSON.deserialize('1985-01-01 00:00:00.000',Datetime.class);
system.debug(Date.newInstance(effectiveDt.yearGmt(), effectiveDt.monthGmt(), effectiveDt.dayGmt()));


Datetime effectiveDtISO = (Datetime) JSON.deserialize('1985-01-01T00:00:00',Datetime.class);
system.debug(Date.newInstance(effectiveDtISO.yearGmt(), effectiveDtISO.monthGmt(), effectiveDtISO.dayGmt()));

Credits go to this thread which i have referred : Parsing an ISO 8601 timestamp to a DateTime

OP Example modified

String strDate1 = '2020-01-01T11:50:50.000Z';
String strDate2 = '2019-01-01 11:50:55';

Datetime date1 = (Datetime)JSON.deserialize( strDate1 ,Datetime.class);
Datetime date2 = (Datetime)JSON.deserialize( strDate2 ,Datetime.class);

System.debug('Date 1 = ' + Date.newInstance(date1.yearGmt(),date1.monthGmt(),date1.dayGmt()));
System.debug('Date 2 = ' + Date.newInstance(date2.yearGmt(),date2.monthGmt(),date2.dayGmt()));

OP mentioned that day and month i always showing 01. 2 points:

  1. datetime string will be needed in double quotes ( my mistake i disregarded that previously)
  2. deserialize method is only working with proper iso format after using double hence we can check if date is in iso format then deserialize it otherwise just get value of datetime using datetime.valueof

String strDate1 = '2017-12-17T11:50:50.000Z'; String strDate2 = '2016-11-16 11:50:55';

Datetime date1 = (DateTime)(strDate1.contains('T')?(Datetime)JSON.deserialize('"' + strDate1 + '"' ,Datetime.class) : DateTime.valueof(strDate1)); Datetime date2 = (Datetime)(strDate2.contains('T')?(Datetime)JSON.deserialize('"' + strDate2 + '"' ,Datetime.class) : DateTime.valueof(strDate2));

System.debug('date 1 = ' + date1); System.debug('date 2 = ' + date2); System.debug('date11 = ' + Date.newInstance(date1.yearGmt(),date1.monthGmt(),date1.dayGmt())); System.debug('Date 21 = ' + Date.newInstance(date2.yearGmt(),date2.monthGmt(),date2.dayGmt()));

====================================================================== Updated Solution

String strDate1 = '2020-01-01T11:50:50.000Z';
Datetime strDate1 = (strDate1==null)?null:Datetime.valueOf(strDate1.replace('T',' '));
Datetime date1 = Date.newInstance(strDate1.yearGmt(),strDate1.monthGmt(),strDate1.dayGmt());

====================================================================== And, this solution works perfectly irrespective of whether the date comes in ISO8601 format or UTC format.

Related Topic