from datetime import datetime
import itertools


def satisfies(query, **kwargs):
    """Check whether a given datetime object satisfies day and time predicates

    Keyword Args:
        month: The month predicate (January, February, ...)
        day: The day of month predicate [1 31)
        weekday: The day of week predicate (Sunday, Monday, ...)
        hour: The hour of day predicate [0 24)
        minute: The minute of hour predicate [0 60)
    """
    formatters = {
        'month': lambda: datetime.strftime(query, '%B'),
        'weekday': lambda: datetime.strftime(query, '%A'),
        'day': lambda: query.day,
        'hour': lambda: query.hour,
        'minute': lambda: query.minute
    }

    attributes = kwargs.keys()
    predicates = itertools.product(*kwargs.values())

    for values in predicates:
        if all([formatters[attr]() == value for attr,value in zip(attributes,values)]):
            return True
    return False