REST API Time vs. XML-RPC API Time - timestamps are not the same

I am using the infusionsoft php library (https://github.com/infusionsoft/infusionsoft-php) and I have setup a REST hook to react to when an opportunity’s stage is changed (opportunity.stage_move event).

Basically I would like to know when a stage has changed on a opportunity and depending on what stage it was moved out of / to do something.

The REST hook tells me the opportunity ID and the timestamp. Ex:
{
“event_key”:“opportunity.stage_move”,
“object_type”:“opportunity”,
“object_keys”:[
{
“apiUrl”:“https://api.infusionsoft.com/crm/rest/v1/opportunities/8733”,
“id”:8733,
“timestamp”:“2019-08-13T19:32:09Z”
}
],
“api_url”:""
}

I need to know the stage it was on and moved to. I can lookup the moves on the StageMove table via infusionsoft->data()->query using the Opportunity ID to get all of it’s moves. The hard part is being sure to get the right move, as sometimes an opportunity is moved through several stages within seconds of each other (just how our workflow works sometimes). So if I lookup the most recent move, it may not reflect the the specific move that was triggered.

You would think I could just compare the MoveDate field from data()->query with the timestamp received from the hook. However, the very same stage move date/time from data()->query is in a different timezone:

[0] => Array
    (
        [MoveToStage] => 5
        [CreatedBy] => 474947
        [OpportunityId] => 8733
        [MoveDate] => DateTime Object
            (
                [date] => 2019-08-13 15:32:09.000000
                [timezone_type] => 3
                [timezone] => UTC
            )

        [UserId] => 473844
        [PrevStageMoveDate] => DateTime Object
            (
                [date] => 2019-08-13 15:26:17.000000
                [timezone_type] => 3
                [timezone] => UTC
            )

        [MoveFromStage] => 18
        [DateCreated] => DateTime Object
            (
                [date] => 2019-08-13 15:32:09.000000
                [timezone_type] => 3
                [timezone] => UTC
            )

        [Id] => 22199
    )

2019-08-13T19:32:09Z (hook) is not the same as 2019-08-13 15:32:09.000000 (MoveDate), there is a 4 hour difference.

2019-08-13T19:32:09Z is in fact in UTC, however data()->query datetime objects have their timezone set to UTC, despite the dates being 4 hours off of UTC.

At a bit of a loss as to why data()->query’s dates are not actually in UTC despite that being the timezone set in the DateTime object?

I cannot compare the timestamps either, they are 2 different timestamps since it thinks they are both in UTC:
2019-08-13T19:32:09Z = 1565724729
2019-08-13 15:32:09.000000 = 1565710329

Been awhile, does anyone have any input into why REST and the XML-RPC APIs are providing dates that are not in the same timezone, despite both claiming to be UTC which means they do not match?

The servers themselves are in EST so some dates return as that. It’s been known about for some time that these dates would make more sense in the user timezone but there would be a significant amount of adjusting to code for IS to correct it so I’m not sure how (or if) that’s coming along.

The infusionsoft servers being in one timezone or another is not a problem, the problem is that the date they send you claims to be in UTC time but is actually an EST date, which means the timestamp is off by 4 hours… If the date they sent you claimed to be in EST instead then there would be no problem as the timestamp would be the same no matter what timezone your server was in.

And the additional weirdness is that the 2 APIs are not returning dates in the same timezone, the REST api gives dates in UTC which are UTC, and the XML api returns dates that are in EST but claim UTC.