The Benetrator
The Benetrator

Reputation: 367

Outlook Items.Restrict() only working for a date 'range' and not an exact date

I'm trying to filter for a single email (MailItem).

When I try to use the .Restrict() method (I also have the exact same issue with .find()) on a list of Outlook.Items from an Outlook.Folder, I can't seem to do so by ReceivedTime date - unless it's a date range.

Example (where I know there should be one result):

Outlook.Items outlookEmails = inboxFolder.Items;
filter = $"[ReceivedTime] = '{myDate.ToString("g")}'";
Outlook.Items distilledList = outlookEmails.Restrict(filter);

The above yeilds a distilledList.Count of 0

However, if I add search for a range that is one mintute either side of the target DateTime like so:

Outlook.Items outlookEmails = inboxFolder.Items;
filter = $"[ReceivedTime] >='{myDate.AddMinutes(-1).ToString("g")}' 
    and [ReceivedTime] <= '{myDate.AddMinutes(1).ToString("g")}'";
Outlook.Items distilledList = outlookEmails.Restrict(filter);

It now yeilds a distilledList.Count of 1 - of course this is because there is only one email received in that time, but it could easily be more

I've been struggling with this for 3 days now and can't work out why. I can't settle for the 'range' really, as I need to get a single email, not all emails recieved within that minute - any help would be hugely appreciated, thank you.

Upvotes: 0

Views: 503

Answers (2)

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66225

That is to be expected. MAPI (and most MAPI store providers internally) store date/time values in the FILETIME structure, which stores values with the 100 ns precision. Outlook Object Model (through COM) exposes date/time values as 8 byte float values with integer part storing days since 1/1/1899 and the fractional part storing the time of the day. Outlook Object Model and its UI always round date/time values to a minute (yuck)

Even if you were to specify a precise value up to milliseconds, round-off errors will be unavoidable and there will never be an exact match (=). You need to always use a range with date/time values.

Upvotes: 1

Eugene Astafiev
Eugene Astafiev

Reputation: 49395

Outlook evaluates time according to that specified time format without seconds. If you specify seconds in the date-time comparison string, the filter will not operate as expected. Dmitry have already explained why it happens technically.

Although dates and times are typically stored with a date format, filters using the Jet and DAV Searching and Locating (DASL) syntax require that the date-time value to be converted to a string representation. In Jet syntax, the date-time comparison string should be enclosed in either double quotes or single quotes. In DASL syntax, the date-time comparison string should be enclosed in single quotes.

When an explicit built-in property is referenced in a Jet query with its explicit string name, the comparison evaluates the property value and the date-time comparison string as local time values.

When a property is referenced in a DASL query by namespace, the comparison evaluates the property value and the date-time comparison string as Coordinated Universal Time (UTC) values.

Upvotes: 1

Related Questions