Search code examples
phpdatetimeimap

PHP imap_search UNSEEN SINCE date with time


I am using PHP imap_search to fetch list of unseen messages since a given date like this:

imap_search($stream, 'UNSEEN SINCE 20-Sep-2015');

This is working fine. However, I am periodically every few minutes checking for new emails and then storing the last check time in a session. I want to be able to run the imap_search with the UNSEEN SINCE date including time. But it just does not seem to work. I've tried:

imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000 (UTC)');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03');

Nothing seems to work. Any ideas if this can be done?


Solution

  • Looking at the definition of SINCE in RFC 3501:

      SINCE <date>
         Messages whose internal date (disregarding time and timezone)
         is within or later than the specified date.
    

    And a date is defined as just a date, without a time:

    date            = date-text / DQUOTE date-text DQUOTE
    
    date-day        = 1*2DIGIT
                        ; Day of month
    
    date-month      = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
                      "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
    
    date-text       = date-day "-" date-month "-" date-year
    
    date-year       = 4DIGIT
    

    So you can't use SINCE to search for messages based on a time more specific than a day.


    Another way to do this is to remember the UID of the latest message you've seen, and then search for messages above that:

    imap_search($stream, 'UID ' . $latest_uid . ':*', SE_UID);
    

    The SE_UID option is required to make imap_search return UIDs instead of message sequence numbers.

    To get the UID of the latest message in the first place, search for *, which represents the highest-numbered message in the mailbox:

    imap_search($stream, 'UID *', SE_UID);