diff --git a/discord/client.py b/discord/client.py index e8e5d6b32..688e76e4b 100644 --- a/discord/client.py +++ b/discord/client.py @@ -51,6 +51,7 @@ import logging, traceback import sys, re import tempfile, os, hashlib import itertools +import datetime from random import randint as random_integer PY35 = sys.version_info >= (3, 5) @@ -1167,10 +1168,12 @@ class Client: The channel to obtain the logs from. limit : int The number of messages to retrieve. - before : :class:`Message` - The message before which all returned messages must be. - after : :class:`Message` - The message after which all returned messages must be. + before : :class:`Message` or `datetime` + The message or date before which all returned messages must be. + If a date is provided it must be a timezone-naive datetime representing UTC time. + after : :class:`Message` or `datetime` + The message or date after which all returned messages must be. + If a date is provided it must be a timezone-naive datetime representing UTC time. Raises ------ @@ -1210,9 +1213,15 @@ class Client: } if before: - params['before'] = before.id + if isinstance(before, datetime.datetime): + params['before'] = utils.time_snowflake(before, high=False) + else: + params['before'] = before.id if after: - params['after'] = after.id + if isinstance(after, datetime.datetime): + params['after'] = utils.time_snowflake(after, high=True) + else: + params['after'] = after.id response = yield from self.session.get(url, params=params, headers=self.headers) log.debug(request_logging_format.format(method='GET', response=response)) diff --git a/discord/utils.py b/discord/utils.py index 9f8f856a8..d9e7bddde 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -106,6 +106,24 @@ def snowflake_time(id): """Returns the creation date in UTC of a discord id.""" return datetime.datetime.utcfromtimestamp(((int(id) >> 22) + DISCORD_EPOCH) / 1000) +def time_snowflake(datetime_obj, high=False): + """Returns a numeric snowflake pretending to be created at the given date. + + When using as the lower end of a range, use time_snowflake(high=False) - 1 to be inclusive, high=True to be exclusive + When using as the higher end of a range, use time_snowflake(high=True) + 1 to be inclusive, high=False to be exclusive + + Parameters + ----------- + datetime_obj + A timezone-naive datetime object representing UTC time. + high + Whether or not to set the lower 22 bit to high or low. + """ + unix_seconds = (datetime_obj - type(datetime_obj)(1970, 1, 1)).total_seconds() + discord_millis = int(unix_seconds * 1000 - DISCORD_EPOCH) + + return (discord_millis << 22) + (2**22-1 if high else 0) + def find(predicate, seq): """A helper to return the first element found in the sequence that meets the predicate. For example: ::