I have the impression you have the impression I ignore this simple solution. 
No, it is not about ignoring the solution. It is the cause of the in your eyes faulty conversion from DateTimeToUnix vs UnixToDateTime combined with the fact that DateTimeToStr simply truncates the result (so that you do not notice the difference).
Also in your solution you can compensate whatever you want inside DT2Number but the fact is that your original DateTime value still contains milliseconds.
So, you end up having two datetime values
1) the one your started out with containing milliseconds
2) the one converted back to datetime, not containing milliseconds (well truncated msecs that is).
Compare these two and they keep mismatching.
It does not matter how DateTimeToUnix converts the DT value. DateTimeToUnix rounds the given DT value while DateTimeToStr simply truncates.
You expect DateTimeToUnix function to do the same truncation, and it (currently) doesn't.
That is why you got the mismatch when printing both values using DateTimeToStr.
Now, having said that, we now know that DateTimeToUnix act differently then its Delphi counterpart. But that is the only reason it needs to be corrected. I personally do not consider that to be a bug but simply how FPC implementation of DateTimeToUnix currently works.
I've now put up almost 10 posts showing the real culprit, i'll stop adding more as i seem to fail to bring the point accross. Please read it again whenever you find yourself in a similar situation of mixing values using different resolutions and when they appear to not match up again when comparing. The answer is here
