Mark Williams 14 Posted November 13, 2020 I want to extract the UTC date time that an email was sent. I cannot work out whether I can just read TIDMessage's Date property or if I have to read the Date header. I am in a time zone that is currently aligned with UTC so I can't tell whether the Date property is UTC or local! Share this post Link to post
Mark Williams 14 Posted November 13, 2020 Easy solution. Just read an older email when UK time was not aligned with UTC! The answer for anyone interested is that TIDMessage's date property shows the UTC time. Share this post Link to post
Remy Lebeau 1436 Posted November 13, 2020 (edited) 6 hours ago, Mark Williams said: TIDMessage's date property shows the UTC time The TIdMessage.Date property is expressed in LOCAL TIME, not in UTC. The only way the TIdMessage.Date property would be in UTC is if either the calling machine is actually in the UTC timezone (which you say is the case here), or if Indy can't determine the local machine's timezone correctly. If you want to read an email's original timestamp (which may or may not be in UTC to begin with), you can read the raw 'Date' header via the TIdMessage.Headers.Values['Date] property. But then you will have to parse the string yourself. Edited November 13, 2020 by Remy Lebeau 1 Share this post Link to post
Mark Williams 14 Posted November 14, 2020 (edited) I have tested with an email from September when UK was + 1 hour ahead of UTC. I get the following results: IDMessage1.Date =25/09/2020 08:31:34 Date header: Fri, 25 Sep 2020 09:31:34 +0100 Both parties in UK. The email was received by me just after 09:31 local time. Of course, that doesn't mean it was sent at 9.31. It could have been sent at 8.31 I suppose. I just changed the clock on my pc to a date where UTC different from local time and I then sent myself an email. The results were: IDMessage.Date=14/08/2020 09:02:26 Date Header: Fri, 14 Aug 2020 10:02:26 +0100 The pc clock was at 10:02 when I sent the email. So the date header is showing the local time. IDMessage date seems to me to be showing UTC time. The function for reading the date header in IDGlobalProtocols is: function GMTToLocalDateTime(S: string): TDateTime; var DateTimeOffset: TDateTime; begin if RawStrInternetToDateTime(S, Result) then begin DateTimeOffset := GmtOffsetStrToDateTime(S); {-Apply GMT and local offsets} Result := Result - DateTimeOffset; Result := {$IFDEF HAS_UniversalTimeToLocal}UniversalTimeToLocal(Result){$ELSE}Result + OffsetFromUTC{$ENDIF}; end; end; As I read it, it is converting the date header to a datetime and then deducting the value of the DateTimeOffSet. As the date header (at least in my case) is showing the local time in any event, deducting the offset is going to produce the UTC time. Am I misunderstanding something? Edited November 14, 2020 by Mark Williams Share this post Link to post
Mark Williams 14 Posted November 14, 2020 (edited) 2 hours ago, Mark Williams said: Am I misunderstanding something? To answer my own question "Yes I am". I can now see the function is converting the datetime to local time after deducting the offset. My error was to change the date on my pc back to the current date before reading the email with TIDMessage. The conversion from UniversalToLocal was being done at today's date when UTC is same as current date time. If I reset my clock back to August and read it again the IDMessage.Date reads the time as 10:02:026 which was the correct local time in August in UK. All very confusing! Of course, the same is also true for my original test with an unfaked email. Oh, the joys of living in a country which insists on changing the time twice a year! Edited November 14, 2020 by Mark Williams Share this post Link to post