Jump to content
Mark Williams

TIDMessage Date

Recommended Posts

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

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
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 by Remy Lebeau
  • Thanks 1

Share this post


Link to post

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 by Mark Williams

Share this post


Link to post
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 by Mark Williams

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×