How to convert this paypal date format to a valid salesforce date

datetimepaypal

Paypal is sending dates to my Rest service in this format 09:30:12 Jan 02, 2022 PST
If I use the DateTime.valueOf() function to translate the value to a DateTime field, it fails with an invalid date/time format error.

Is there any built-in functionality in Apex that will help me convert this format to a DateTime field?
I am going through the documentation but haven't found anything yet.

The values being sent by Paypal IPN are being sent in the request.params

An example of the params being sent by the IPN.I have captured these in the user debug logs.

USER_DEBUG|[24]|DEBUG|business ==> [email protected]
USER_DEBUG|[24]|DEBUG|payment_status ==> Completed
USER_DEBUG|[24]|DEBUG|mc_currency ==> USD
USER_DEBUG|[24]|DEBUG|shipping_discount ==> 0.00
USER_DEBUG|[24]|DEBUG|txn_type ==> web_accept
USER_DEBUG|[24]|DEBUG|mc_gross ==> 466.78
USER_DEBUG|[24]|DEBUG|ipn_track_id ==> 11eacc648df9b
USER_DEBUG|[24]|DEBUG|payment_date ==> 09:30:12 Jan 02, 2022 PST

Best Answer

There's nothing you can do. Manual parsing is required. This isn't as bad as it sounds though, as you can:

public static DateTime parsePaypalIpnDate(String theDate) {
    String[] months = new String[] { '', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' };
    Pattern ipnDatePattern = Pattern.compile('(\\d+):(\\d+):(\\d+) (\\w+) (\\d+), (\\d+) (\\w+)');
    Matcher dateMatcher = ipnDatePattern.matcher(theDate);
    dateMatcher.find();
    Integer hour = Integer.valueOf(dateMatcher.group(1));
    Integer minute = Integer.valueOf(dateMatcher.group(2));
    Integer second = Integer.valueOf(dateMatcher.group(3));
    Integer month = months.indexOf(dateMatcher.group(4));
    Integer day = Integer.valueOf(dateMatcher.group(5));
    Integer year = Integer.valueOf(dateMatcher.group(6));
    String timeZoneName = dateMatcher.group(7);
    TimeZone paypalTimeZone = TimeZone.getTimeZone(timeZoneName);
    DateTime timeAsGmt = DateTime.newInstanceGMT(year, month, day, hour, minute, second);
    Integer timeZoneOffset = paypalTimeZone.getOffSet(timeAsGMT);
    DateTime timeAsIntended = timeAsGmt.addSeconds(timeZoneOffset/1000);
    return timeAsIntended;
}

Note that this might be an hour off when it's within 24 hours of DST changes, when applicable, as I'm not sure there's a valid indicator for DST changes.

Related Topic